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

[WIP] Simulation form conversion #9111

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
import { componentTypes, validatorTypes } from '@@ddf';

const createSchema = (resolve, max_name_length, url, ae_ansible_custom_button, form_action, ae_custom_button, attr_values_pairs, maxlength) => {
const fields = [
{
component: componentTypes.SELECT,
id: 'instance_name',
name: '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 })),
onChange: (value) => miqSelectPickerEvent(value, url),
url: url,
},
{
id: 'simulationParameters',
component: componentTypes.PLAIN_TEXT,
name: 'simulationParameters',
label: __('Simulation Parameters'),
style: { fontSize: '16px' }
},
{
component: componentTypes.CHECKBOX,
id: 'readonly',
name: 'readonly',
label: __('Execute Methods'),
initialValue: resolve.new.readonly !== true,
title : "Simulation parameters"
},
{
id: 'AttributeValuePairs',
component: componentTypes.PLAIN_TEXT,
name: 'AttributeValuePairs',
label: __('Attribute/Value Pairs'),
style: { fontSize: '16px' }
},
];

if (!ae_ansible_custom_button) {
fields.splice(1, 0, {
component: componentTypes.TEXT_FIELD,
id: 'object_message',
name: 'object_message',
label: __('Message'),
maxLength: max_name_length,
initialValue: resolve.new.object_message,
validate: [{ type: validatorTypes.REQUIRED }],
isRequired: true
}),
fields.splice(2, 0, {
component: componentTypes.TEXT_FIELD,
id: 'object_request',
name: 'object_request',
label: __('Request'),
initialValue: resolve.new.object_request,
validate: [{ type: validatorTypes.REQUIRED }],
});
}

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

if (form_action != "miq_action") {
if (ae_custom_button) {
fields.splice(3, 0, {
id: 'objectAttribute_1',
component: componentTypes.PLAIN_TEXT,
name: 'objectAttribute_1',
label: __('Object Attribute 1'),
style: { fontSize: '16px' }
}),
fields.splice(4, 0, {
component: componentTypes.TEXT_FIELD,
name: 'object_attribute_1',
label: __('Type'),
isReadOnly: true,
content: `${_("Type")}: ${ui_lookup({ model: resolve.target_class })}`,
})
} else {
const targetClassesOptions = [
{ label: "<none>", value: null },
...Object.entries(resolve.target_classes).map(([key, value]) => ({ label: key, value: value }))
];
fields.splice(3, 0, {
id: 'objectAttribute',
component: componentTypes.PLAIN_TEXT,
name: 'objectAttribute',
label: __('Object Attribute'),
style: { fontSize: '16px' }
}),
fields.splice(4, 0, {
component: componentTypes.SELECT,
id: 'target_class',
name: 'target_class',
label: __('Type'),
initialValue: resolve.new.target_class,
validate: [{ type: validatorTypes.REQUIRED }],
isSearchable: true,
simpleValue: true,
options: targetClassesOptions,
onChange: (value) => miqSelectPickerEvent(value, url),
url: url,
})
}
}

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

fields.push(
{
component: componentTypes.PLAIN_TEXT,
id: labelKey,
name: labelKey,
label: `${i + 1}`,
style: {fontWeight: 'bold'}
},
{
component: componentTypes.TEXT_FIELD,
id: f,
name: f,
maxLength: maxlength,
validate: [{ type: validatorTypes.REQUIRED }],
fieldprops: {
className: 'form-control col-md-4',
'data-miq_observe': JSON.stringify({ interval: '.5', url: url })
}
},
{
component: componentTypes.TEXT_FIELD,
id: v,
name: v,
maxLength: maxlength,
validate: [{ type: validatorTypes.REQUIRED }],
fieldprops: {
className: 'form-control col-md-4',
'data-miq_observe': JSON.stringify({ interval: '.5', url: url })
}
}
);
})

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

export default createSchema;
58 changes: 58 additions & 0 deletions app/javascript/components/automate-simulation/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import React, { useState, useEffect } from 'react';
import MiqFormRenderer from '@@ddf';
import PropTypes from 'prop-types';
import createSchema from './automate-simulation.schema';
import miqRedirectBack from '../../../../app/javascript/helpers/miq-redirect-back';

const AutomateSimulation = ({ resolve, title, max_name_length, url, ae_ansible_custom_button, form_action, ae_custom_button, attr_values_pairs, maxlength }) => {

const handleSubmit = (values) => {
fetch(url, {
method: 'POST',
body: JSON.stringify(values),
headers: {
'Content-Type': 'application/json'
},
})
.then(response => {
const message = __('Automation Simulation options submitted');
const url = '/miq_ae_tools/resolve'
miqRedirectBack(message, 'success', url);
})
.catch(error => {
miqRedirectBack(error, 'error', url);
});
};

return(
<MiqFormRenderer
schema={createSchema(resolve, max_name_length, url, ae_ansible_custom_button, form_action, ae_custom_button, attr_values_pairs, maxlength)}
onSubmit={handleSubmit}
/>
);
};

AutomateSimulation.propTypes = {
resolve: PropTypes.object.isRequired,
title: PropTypes.string.isRequired,
max_name_length: PropTypes.number.isRequired,
url: PropTypes.string.isRequired,
ae_ansible_custom_button: PropTypes.bool.isRequired,
form_action: PropTypes.string.isRequired,
ae_custom_button: PropTypes.bool.isRequired,
attr_values_pairs: PropTypes.array.isRequired,
maxlength: PropTypes.number.isRequired,
};

AutomateSimulation.defaultProps = {
recordId: undefined,
title: undefined,
max_name_length: undefined,
url: undefined,
ae_ansible_custom_button: undefined,
form_action: undefined,
ae_custom_button: undefined,
attr_values_pairs: undefined,
maxlength: undefined,
};
export default AutomateSimulation;
2 changes: 2 additions & 0 deletions app/javascript/packs/component-definitions-common.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import AnsibleRepositoryForm from '../components/ansible-repository-form';
import AttachDetachCloudVolumeForm from '../components/cloud-volume-form/attach-detach-cloud-volume-form';
import AuthKeypairCloudForm from '../components/auth-key-pair-cloud';
import AutomationSimulation from '../components/AutomationSimulation';
import AutomateSimulation from '../components/automate-simulation';
import ButtonList from '../components/data-tables/button-list';
import ButtonGroupList from '../components/data-tables/button-group-list';
import CatalogForm from '../components/catalog-form/catalog-form';
Expand Down Expand Up @@ -188,6 +189,7 @@ ManageIQ.component.addReact('AnsibleRepositoryForm', AnsibleRepositoryForm);
ManageIQ.component.addReact('AttachDetachCloudVolumeForm', AttachDetachCloudVolumeForm);
ManageIQ.component.addReact('AuthKeypairCloudForm', AuthKeypairCloudForm);
ManageIQ.component.addReact('AutomationSimulation', AutomationSimulation);
ManageIQ.component.addReact('AutomateSimulation', AutomateSimulation);
ManageIQ.component.addReact('BreadcrumbsBar', BreadcrumbsBar);
ManageIQ.component.addReact('ButtonList', ButtonList);
ManageIQ.component.addReact('ButtonGroupList', ButtonGroupList);
Expand Down
129 changes: 12 additions & 117 deletions app/views/layouts/_ae_resolve_options.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -4,120 +4,15 @@
- ae_ansible_custom_button ||= false
- rec_id = @edit && @edit[:action_id].present? ? @edit[:action_id] : "new"
- url = url_for_only_path(:action => field_changed_url, :id => rec_id)
.form
- if form_action == "ae_resolve" && !ae_ansible_custom_button
%h3
= _("Object Details")
.form-group
%label.control-label
= _("System/Process")

= select_tag('instance_name',
options_for_select(resolve[:instance_names].sort_by(&:downcase),
resolve[:new][:instance_name]),
"data-miq_sparkle_on" => true,
"data-miq_sparkle_off" => true,
:class => "selectpicker form-control")
:javascript
miqInitSelectPicker();
miqSelectPickerEvent('instance_name', "#{url}")
- unless ae_ansible_custom_button
.form-group
%label.control-label
= _("Message")

= text_field_tag("object_message",
resolve[:new][:object_message],
:maxlength => ViewHelper::MAX_NAME_LEN,
:class => "form-control form-control",
"data-miq_observe" => {:interval => '.5',
:url => url}.to_json)
= javascript_tag("if (!$('#description').length) #{javascript_focus('object_message')}")
.form-group
%label.control-label
= _("Request")

= text_field_tag("object_request",
resolve[:new][:object_request],
:maxlength => ViewHelper::MAX_NAME_LEN,
:class => "form-control form-control",
"data-miq_observe" => {:interval => '.5', :url => url}.to_json)
- if form_action != "miq_action"
- if ae_custom_button
%hr
%h3
= _("Object Attribute 1")
.form-horizontal
.form-group
%label.control-label
= _("Type")
.col-md-8
= ui_lookup(:model => @resolve[:target_class])
- else
%hr
%h3
= _("Object Attribute")
.form
.form-group
%label.control-label
= _("Type")

= select_tag('target_class',
options_for_select([["<#{_('None')}>", nil]] + resolve[:target_classes].invert.to_a,
resolve[:new][:target_class]),
"data-miq_sparkle_on" => true,
"data-miq_sparkle_off" => true,
:class => "selectpicker form-control")
:javascript
miqInitSelectPicker();
miqSelectPickerEvent('target_class', "#{url}")
- if resolve[:new][:target_class] && !resolve[:new][:target_class].blank? && resolve[:targets]
.form-group
%label.control-label
= _("Selection")

= select_tag('target_id',
options_for_select([["<#{_('Choose')}>", nil]] + resolve[:targets],
resolve[:new][:target_id]),
"data-miq_sparkle_on" => true,
"data-miq_sparkle_off" => true,
:class => "selectpicker form-control")
:javascript
miqInitSelectPicker();
miqSelectPickerEvent('target_id', "#{url}")
- if ae_sim_form
%hr
%h3
= _("Simulation Parameters")
.form
.form-group
%label.control-label
= _("Execute Methods")
= check_box_tag("readonly",
"1",
resolve[:new][:readonly] != true,
"data-miq_observe_checkbox" => {:url => url}.to_json)
%hr
%h3
= _("Attribute/Value Pairs")
.form-horizontal
- ApplicationController::AE_MAX_RESOLUTION_FIELDS.times do |i|
- f = "attribute_" + (i + 1).to_s
- v = "value_" + (i + 1).to_s
.form-group
%label.col-md-2.control-label
= (i + 1).to_s
.col-md-4
= text_field_tag(f,
resolve[:new][:attrs][i][0],
:maxlength => ViewHelper::MAX_NAME_LEN,
:class => "form-control",
"data-miq_observe" => {:interval => '.5',
:url => url}.to_json)
.col-md-4
= text_field_tag(v,
resolve[:new][:attrs][i][1],
:maxlength => ViewHelper::MAX_NAME_LEN,
:class => "form-control",
"data-miq_observe" => {:interval => '.5',
:url => url}.to_json)
= react('AutomateSimulation',
:resolve => resolve,
:title => ui_lookup(:model => @resolve[:title]),
:max_name_length => ViewHelper::MAX_NAME_LEN,
:readonly => resolve[:new][:readonly],
:url => url,
:ae_ansible_custom_button => ae_ansible_custom_button,
:form_action => form_action,
:ae_custom_button => ae_custom_button,
:attr_values_pairs => ApplicationController::AE_MAX_RESOLUTION_FIELDS.times,
:maxlength => ViewHelper::MAX_NAME_LEN,
:submit_url => url)
1 change: 1 addition & 0 deletions app/views/miq_ae_tools/_resolve_form.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#form_div
= render :partial => "layouts/flash_msg"
- if @resolve[:instance_names]
-# %p= @resolve.inspect
= render(:partial => "layouts/ae_resolve_options",
:locals => {:resolve => @resolve,
:form_action => "ae_resolve",
Expand Down