Skip to content

Commit

Permalink
Convert automate simulation form and combine with summary comtponent
Browse files Browse the repository at this point in the history
  • Loading branch information
liu-samuel committed Nov 6, 2024
1 parent 64b9d6d commit e7618d9
Show file tree
Hide file tree
Showing 22 changed files with 1,406 additions and 176 deletions.
29 changes: 20 additions & 9 deletions app/controllers/application_controller/automate.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
module ApplicationController::Automate
extend ActiveSupport::Concern
include MiqAeToolsHelper

def resolve_button_throw
if valid_resolve_object?
Expand All @@ -21,15 +22,7 @@ def resolve_button_throw
add_flash(_("Automation Error: %{error_message}") % {:error_message => bang.message}, :error)
end
end
render :update do |page|
page << javascript_prologue
page.replace("left_cell_bottom", :partial => "resolve_form_buttons")
page.replace("flash_msg_div", :partial => "layouts/flash_msg")
page << "miqScrollTop();" if @flash_array.present?
page.replace_html("main_div", :partial => "results_tabs")
page << javascript_reload_toolbars
page << "miqSparkle(false);"
end
automation_simulation_data(@ae_simulation_tree, @results, @resolve)
end
private :resolve_button_throw

Expand Down Expand Up @@ -115,6 +108,24 @@ def resolve_button_reset_or_none
end
private :resolve_button_reset_or_none

def resolve_automate_simulation
custom_button_redirect = params[:button] == 'simulate' || params[:simulate] == 'simulate'
assert_privileges(custom_button_redirect ? 'ab_button_simulate' : 'miq_ae_class_simulation')
@explorer = true
@breadcrumbs = []
drop_breadcrumb(:name => _("Resolve"), :url => "/miq_ae_tools/resolve")
@lastaction = "resolve"
@right_cell_text = _("Simulation")
get_simulation_form_vars
case params[:button]
when "throw", "retry" then resolve_button_throw
when "copy" then resolve_button_copy
when "paste" then resolve_button_paste
when "simulate" then resolve_button_simulate
else resolve_button_reset_or_none
end
end

def resolve
custom_button_redirect = params[:button] == 'simulate' || params[:simulate] == 'simulate'
assert_privileges(custom_button_redirect ? 'ab_button_simulate' : 'miq_ae_class_simulation')
Expand Down
47 changes: 47 additions & 0 deletions app/controllers/miq_ae_tools_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,51 @@ def reset_datastore
javascript_flash(:spinner_off => true)
end

def get_simulation_form_vars
assert_privileges('miq_ae_class_simulation')
if params[:object_request]
@resolve[:new][:object_request] = params[:object_request]
end
if params.key?(:starting_object)
@resolve[:new][:starting_object] = params[:starting_object]
@resolve[:new][:instance_name] = nil
end
if params[:readonly]
@resolve[:new][:readonly] = (params[:readonly] != "1")
end

copy_params_if_present(@resolve[:new], params, %i[instance_name other_name object_message object_request target_class target_id])

ApplicationController::AE_MAX_RESOLUTION_FIELDS.times do |i|
ApplicationController::AE_MAX_RESOLUTION_FIELDS.times do |i|
f = ("attribute_" + (i + 1).to_s)
v = ("value_" + (i + 1).to_s)
@resolve[:new][:attrs][i][0] = params[f.to_sym] || nil
@resolve[:new][:attrs][i][1] = params[v.to_sym] || nil
end
end
@resolve[:new][:target_id] = nil if params[:target_class] == ""
copy_params_if_present(@resolve, params, %i[button_text button_number])
@resolve[:throw_ready] = ready_to_throw
end

def get_form_targets
assert_privileges('miq_ae_class_simulation')
if params.key?(:target_class) && params[:target_class] != '-1'
targets = Rbac.filtered(params[:target_class]).select(:id, *columns_for_klass(params[:target_class])) if params[:target_class].present?
unless targets.nil?
@resolve[:targets] = targets.sort_by { |t| t.name.downcase }.collect { |t| [t.name, t.id.to_s] }
if !@resolve[:target_id]
@resolve[:target_id] = nil
end
end
end

render_json = {}
render_json[:targets] = @resolve[:targets] if @resolve[:targets].present?
render :json => render_json
end

private ###########################

def automate_import_json_serializer
Expand Down Expand Up @@ -444,6 +489,8 @@ def get_form_vars
@resolve[:new][:attrs][i][0] = params[f] if params[f.to_sym]
@resolve[:new][:attrs][i][1] = params[v] if params[v.to_sym]
end
require 'byebug'
byebug
if params.key?(:target_class)
targets = Rbac.filtered(params[:target_class]).select(:id, *columns_for_klass(params[:target_class])) if params[:target_class].present?
unless targets.nil?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ class ApplicationHelper::Toolbar::MiqAeToolsSimulateCenter < ApplicationHelper::
'fa fa-files-o fa-lg',
N_('Copy object details for use in a Button'),
N_('Copy'),
:url => "resolve",
:url => "resolve?button=copy",
:url_parms => "?button=copy",
:klass => ApplicationHelper::Button::AeCopySimulate),
])
Expand Down
2 changes: 1 addition & 1 deletion app/helpers/miq_ae_tools_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def git_import_submit_help

def automation_simulation_data(tree, results, resolve)
if results
{
render :json => {
:tree => {:text => _('Tree View'), :rows => ae_result_tree(tree)},
:xml => {:text => _('Xml View'), :rows => ae_result_xml(results)},
:object => {:text => _('Object info'), :rows => ae_result_uri(resolve)}
Expand Down
11 changes: 6 additions & 5 deletions app/javascript/components/AutomationSimulation/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@ import MiqStructuredList from '../miq-structured-list';
/** Component to render the summary contents displayed in the Automation / Embedded Automate / Simulation */
const AutomationSimulation = ({ data }) => {
const [tabConfig, setTabConfig] = useState([]);

useEffect(() => {
const config = Object.keys(data).map((name) => ({ name, text: data[name].text }));
setTabConfig(config);
}, []);
if (Object.keys(data).length > 1) {
const config = Object.keys(data).map((name) => ({ name, text: data[name].text }));
setTabConfig(config);
}
}, [data]);

/** Function to render the tabs contents. */
const renderTabContent = (name) => {
Expand All @@ -37,7 +38,7 @@ const AutomationSimulation = ({ data }) => {
</Tabs>
);

return data.notice
return Object.keys(data).length <= 1
? <NotificationMessage type="info" message={data.notice} />
: renderTabs();
};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,239 @@
import { componentTypes, validatorTypes } from '@@ddf';

const targetsURL = (targetClass) => `/miq_ae_tools/get_form_targets?target_class=${encodeURIComponent(targetClass)}`;
const loadTargets = (selectedTargetClass) => http.get(targetsURL(selectedTargetClass))
.then((formVars) => {
if (formVars && formVars.targets) {
return [
{ label: `<${__('None')}>`, value: '-1' },
...formVars.targets.map(([key, value]) => ({
label: String(key),
value: String(value),
})),
];
}
return [];
});

const createSchema = (
resolve, maxNameLength, url, aeAnsibleCustomButton, formAction, aeCustomButton,
attrValuesPairs, maxLength, typeClassesOptions, formData, setFormData,
) => {
const fields = [
{
component: componentTypes.PLAIN_TEXT,
id: 'object_details',
name: 'object_details',
className: 'automate-object-details',
label: __('Object Details'),
style: { fontSize: '16px' },
},

{
component: componentTypes.SELECT,
id: 'instance_name',
name: 'instance_name',
className: 'automate-instance-name',
label: __('System/Process'),
initialValue: resolve.instance_names.sort((b, a) => a.toLowerCase().localeCompare(b.toLowerCase())),
validate: [{ type: validatorTypes.REQUIRED }],
isSearchable: true,
simpleValue: true,
options: resolve.instance_names.map((name) => ({ label: name, value: name })),
url,
},
{
component: componentTypes.TEXT_FIELD,
id: 'object_message',
name: 'object_message',
className: 'automate-object-message',
label: __('Message'),
maxLength: maxNameLength,
initialValue: resolve.new.object_message,
isRequired: true,
},

{
component: componentTypes.TEXT_FIELD,
id: 'object_request',
name: 'object_request',
className: 'automate-object-request',
label: __('Request'),
initialValue: resolve.new.object_request,
},

{
component: componentTypes.PLAIN_TEXT,
id: 'object_attribute',
name: 'object_attribute',
className: 'automate-object-attribute',
label: __('Object Attribute'),
style: { fontSize: '16px' },
},

{
component: componentTypes.SELECT,
id: 'target_class',
name: 'target_class',
label: __('Type'),
options: typeClassesOptions,
initialValue: resolve.new.target_class,
className: 'automate-target-class',
isSearchable: true,
simpleValue: true,
onChange: (targetClass) => {
if (formData.targetClass !== targetClass) {
setFormData((prevData) => ({ ...prevData, targetClass }));
}
},
validate: [
{
type: validatorTypes.REQUIRED,
condition: {
not: {
or: [
{
when: 'target_class',
is: '-1',
},
{
when: 'target_class',
isEmpty: true,
},
],
},
},
},
],
},

{
component: componentTypes.SELECT,
id: 'selection_target',
name: 'selection_target',
label: __('Selection'),
key: `selection_target_${formData.targetClass}`,
className: 'automate-selection-target',
initialValue: resolve.new.target_id,
loadOptions: () => (loadTargets(formData.targetClass)),
condition: {
not: {
or: [
{
when: 'target_class',
is: '-1',
},
{
when: 'target_class',
isEmpty: true,
},
],
},
},
validate: [
{
type: validatorTypes.REQUIRED,
condition: {
not: {
or: [
{
when: 'target_class',
is: '-1',
},
{
when: 'target_class',
isEmpty: true,
},
],
},
},
},
],
},
{
id: 'simulationParameters',
component: componentTypes.PLAIN_TEXT,
name: 'simulationParameters',
className: 'automate-simulation-parameters',
label: __('Simulation Parameters'),
style: { fontSize: '16px' },
},
{
component: componentTypes.CHECKBOX,
id: 'readonly',
name: 'readonly',
className: 'automate-readonly',
label: __('Execute Methods'),
initialValue: resolve.new.readonly,
title: 'Simulation parameters',
},
{
id: 'AttributeValuePairs',
component: componentTypes.PLAIN_TEXT,
name: 'AttributeValuePairs',
label: __('Attribute/Value Pairs'),
style: { fontSize: '16px' },
},
];

if (!document.getElementById('description') && document.getElementById('object_message')) {
document.getElementById('object_message').focus();
}

attrValuesPairs.forEach((_, i) => {
const f = `attribute_${i + 1}`;
const v = `value_${i + 1}`;
const labelKey = `attributeValuePairLabel_${i + 1}`;

const subForm = [
{
component: componentTypes.SUB_FORM,
id: `subform_${i + 1}`,
name: `subform_${i + 1}`,
className: 'subform',
fields: [
{
component: componentTypes.PLAIN_TEXT,
id: labelKey,
name: labelKey,
className: 'attributeValuePairLabel',
label: `${i + 1}`,
style: { fontWeight: 'bold' },
},
{
component: componentTypes.TEXT_FIELD,
id: f,
name: f,
maxLength,
label: ' ',
initialValue: resolve.new.attrs[i][0],
fieldprops: {
className: 'field-input',
'data-miq_observe': JSON.stringify({ interval: '.5', url }),
},
},
{
component: componentTypes.TEXT_FIELD,
id: v,
name: v,
maxLength,
label: ' ',
initialValue: resolve.new.attrs[i][1],
fieldprops: {
className: 'value-input',
'data-miq_observe': JSON.stringify({ interval: '.5', url }),
},
},
],
},
];
fields.push(subForm);
});

return {
title: 'Object Details',
fields,
};
};

export default createSchema;
Loading

0 comments on commit e7618d9

Please sign in to comment.