Skip to content

Commit

Permalink
Introduce support for multi-tab orchestration dialogs
Browse files Browse the repository at this point in the history
Until now it was hard-coded that orchestration service dialog uses
a single tab only, named "Basic Information". For some providers, however,
this is not too convinient because there are many fields in dialog
that can be grouped into multiple tabs.

With this commit we allow provider to decide how many tabs to use
and what content to put in each tab. New feature is optional and fully
backwards compatible.

Usage: should provider decide to define custom tabs, it can now override
function `tabs` that returns a list of tab specifications.

Signed-off-by: Gašper Vrhovšek <[email protected]>
Signed-off-by: Miha Pleško <[email protected]>
  • Loading branch information
gasper-vrhovsek authored and miha-plesko committed May 3, 2018
1 parent a22b03c commit 2472424
Show file tree
Hide file tree
Showing 4 changed files with 203 additions and 14 deletions.
10 changes: 5 additions & 5 deletions app/models/dialog/orchestration_template_service_dialog.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ def self.create_dialog(name, template)

def create_dialog(name, template)
Dialog.new(:name => name, :buttons => "submit,cancel").tap do |dialog|
tab = dialog.dialog_tabs.build(:display => "edit", :label => "Basic Information", :position => 0)
add_stack_group(template.deployment_options, tab, 0)

template.parameter_groups.each_with_index do |parameter_group, index|
add_parameter_group(parameter_group, tab, index + 1)
template.tabs.each_with_index do |data, idx|
tab = dialog.dialog_tabs.build(:display => "edit", :label => data[:title], :position => idx)
offset = data[:stack_group] ? 1 : 0
add_stack_group(data[:stack_group], tab, 0) if data[:stack_group]
Array(data[:param_groups]).each_with_index { |group, i| add_parameter_group(group, tab, i + offset) }
end
dialog.save!
end
Expand Down
10 changes: 10 additions & 0 deletions app/models/orchestration_template.rb
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,16 @@ def self.not_in_use
includes(:stacks).where(:orchestration_stacks => {:orchestration_template_id => nil})
end

def tabs
[
{
:title => "Basic Information",
:stack_group => deployment_options,
:param_groups => parameter_groups
}
]
end

def parameter_groups
raise NotImplementedError, _("parameter_groups must be implemented in subclass")
end
Expand Down
181 changes: 172 additions & 9 deletions spec/models/dialog/orchestration_template_service_dialog_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@
let(:orchestration_template) do
FactoryGirl.create(:orchestration_template).tap do |template|
allow(template).to receive(:parameter_groups).and_return(param_groups)
allow(template).to receive(:tabs).and_return(tabs) if tabs.count > 0
end
end
let(:param_groups) { create_parameters(param_options) }
let(:dialog) { described_class.create_dialog("test", orchestration_template) }
let(:dialog) { described_class.create_dialog("test", orchestration_template) }
let(:tabs) { [] }

describe ".create_dialog" do
let(:param_groups) { [] }
Expand All @@ -17,7 +19,160 @@
)

tabs = dialog.dialog_tabs
assert_tab_attributes(tabs[0])
assert_tab_attributes(tabs[0], :label => "Basic Information", :display => "edit")
end

context "with custom tabs" do
let(:dialog_tabs) { dialog.dialog_tabs }
let(:first_tab) { dialog_tabs.first }
let(:first_group) { first_tab.dialog_groups.first }
let(:second_tab) { dialog_tabs.second }

describe 'tab with stack group' do
let(:tabs) do
[
{
:title => 'Tab 1',
:stack_group => [
template_param(:label => 'Param 1'),
template_param(:label => 'Param 2')
]
}
]
end

it do
expect(dialog_tabs.size).to eq(1)
assert_tab_attributes(first_tab, :label => 'Tab 1', :display => 'edit')
assert_group(first_group, 'Options', ['Param 1', 'Param 2'])
end
end

describe 'tab with param group' do
let(:tabs) do
[
{
:title => 'Tab 1',
:param_groups => [
OrchestrationTemplate::OrchestrationParameterGroup.new(
:label => 'Parameter Group 1',
:parameters => [
template_param(:label => 'Param 1'),
template_param(:label => 'Param 2')
],
)
]
},
]
end

it do
expect(dialog_tabs.size).to eq(1)
assert_tab_attributes(first_tab, :label => 'Tab 1', :display => 'edit')
assert_group(first_group, 'Parameter Group 1', ['Param 1', 'Param 2'])
end
end

describe 'tab with two param groups' do
let(:tabs) do
[
{
:title => 'Tab 1',
:param_groups => [
OrchestrationTemplate::OrchestrationParameterGroup.new(
:label => 'Parameter Group 1',
:parameters => [
template_param(:label => 'Param 1'),
template_param(:label => 'Param 2')
],
),
OrchestrationTemplate::OrchestrationParameterGroup.new(
:label => 'Parameter Group 2',
:parameters => [
template_param(:label => 'Param 3'),
template_param(:label => 'Param 4')
],
)
]
},
]
end

it do
expect(dialog_tabs.size).to eq(1)
assert_group(first_group, 'Parameter Group 1', ['Param 1', 'Param 2'])
assert_group(first_tab.dialog_groups[1], 'Parameter Group 2', ['Param 3', 'Param 4'])
end
end

describe 'tab with stack group and param group' do
let(:tabs) do
[
{
:title => 'Tab 1',
:stack_group => [
template_param(:label => 'Param 1'),
template_param(:label => 'Param 2')
],
:param_groups => [
OrchestrationTemplate::OrchestrationParameterGroup.new(
:label => 'Parameter Group 1',
:parameters => [
template_param(:label => 'Param 3'),
template_param(:label => 'Param 4')
],
)
]
},
]
end

it do
expect(dialog_tabs.size).to eq(1)
assert_tab_attributes(first_tab, :label => 'Tab 1', :display => 'edit')
assert_group(first_group, 'Options', ['Param 1', 'Param 2'])
assert_group(first_tab.dialog_groups[1], 'Parameter Group 1', ['Param 3', 'Param 4'])
end
end

describe 'two tabs' do
let(:tabs) do
[
{
:title => 'Tab 1',
:param_groups => [
OrchestrationTemplate::OrchestrationParameterGroup.new(
:label => 'Parameter Group 1',
:parameters => [
template_param(:label => 'Param 1'),
template_param(:label => 'Param 2')
],
)
]
},
{
:title => 'Tab 2',
:param_groups => [
OrchestrationTemplate::OrchestrationParameterGroup.new(
:label => 'Parameter Group 2',
:parameters => [
template_param(:label => 'Param 3'),
template_param(:label => 'Param 4')
],
)
]
},
]
end

it do
expect(dialog_tabs.size).to eq(2)
assert_tab_attributes(first_tab, :label => 'Tab 1', :display => 'edit')
assert_group(first_group, 'Parameter Group 1', ['Param 1', 'Param 2'])
assert_tab_attributes(second_tab, :label => 'Tab 2', :display => 'edit')
assert_group(second_tab.dialog_groups.first, 'Parameter Group 2', ['Param 3', 'Param 4'])
end
end
end
end

Expand Down Expand Up @@ -99,19 +254,16 @@
end

def assert_stack_tab(tab)
assert_tab_attributes(tab)
assert_tab_attributes(tab, :label => "Basic Information", :display => "edit")

groups = tab.dialog_groups
expect(groups.size).to eq(3)

assert_stack_group(groups[0])
end

def assert_tab_attributes(tab)
expect(tab).to have_attributes(
:label => "Basic Information",
:display => "edit"
)
def assert_tab_attributes(tab, attributes)
expect(tab).to have_attributes(attributes)
end

def assert_stack_group(group)
Expand All @@ -124,7 +276,7 @@ def assert_stack_group(group)
expect(fields.size).to eq(4)

expect(fields[0].resource_action.fqname).to eq("/Cloud/Orchestration/Operations/Methods/Available_Tenants")
assert_field(fields[0], DialogFieldDropDownList, :name => "tenant_name", :dynamic => true, :reconfigurable => false)
assert_field(fields[0], DialogFieldDropDownList, :name => "tenant_name", :dynamic => true, :reconfigurable => nil)
assert_field(fields[1], DialogFieldTextBox, :name => "stack_name", :validator_rule => '^[A-Za-z][A-Za-z0-9\-]*$', :reconfigurable => false)
end

Expand All @@ -133,6 +285,11 @@ def assert_field(field, clss, attributes)
expect(field).to have_attributes(attributes)
end

def assert_group(group, group_label, names)
expect(group.label).to eq(group_label)
expect(group.dialog_fields.map(&:label)).to eq(names)
end

def test_field(dialog)
# First ensure that the dialog is properly constructed.
tabs = dialog.dialog_tabs
Expand All @@ -148,4 +305,10 @@ def create_parameters(options)
options.reverse_merge!(:name => 'user', :label => 'User Parameter', :data_type => 'string', :required => true)
[OrchestrationTemplate::OrchestrationParameterGroup.new(:label => 'group', :parameters => [OrchestrationTemplate::OrchestrationParameter.new(options)])]
end

def template_param(options)
options[:name] ||= SecureRandom.hex
options[:data_type] ||= 'string'
OrchestrationTemplate::OrchestrationParameter.new(options)
end
end
16 changes: 16 additions & 0 deletions spec/models/orchestration_template_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,22 @@
end
end

describe ".tabs" do
it do
expect(subject).to receive(:deployment_options).and_return('deployment-options')
expect(subject).to receive(:parameter_groups).and_return('parameter-groups')
expect(subject.tabs).to eq(
[
{
:title => 'Basic Information',
:stack_group => 'deployment-options',
:param_groups => 'parameter-groups'
}
]
)
end
end

def assert_deployment_option(option, name, constraint_type, required)
expect(option.name).to eq(name)
expect(option.required?).to eq(required)
Expand Down

0 comments on commit 2472424

Please sign in to comment.