diff --git a/app/javascript/components/automate-simulation/automate-simulation.schema.js b/app/javascript/components/automate-simulation/automate-simulation.schema.js new file mode 100644 index 000000000000..ea3bcfa27d71 --- /dev/null +++ b/app/javascript/components/automate-simulation/automate-simulation.schema.js @@ -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, attribute_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: "", 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, + }) + } + } + + attribute_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; diff --git a/app/javascript/components/automate-simulation/index.jsx b/app/javascript/components/automate-simulation/index.jsx new file mode 100644 index 000000000000..2736bbf469ea --- /dev/null +++ b/app/javascript/components/automate-simulation/index.jsx @@ -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, attribute_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( + + ); +}; + +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, + attribute_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, + attribute_values_pairs: undefined, + maxlength: undefined, +}; +export default AutomateSimulation; diff --git a/app/javascript/packs/component-definitions-common.js b/app/javascript/packs/component-definitions-common.js index 6b7e9f572a73..767d2c8c488a 100644 --- a/app/javascript/packs/component-definitions-common.js +++ b/app/javascript/packs/component-definitions-common.js @@ -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'; @@ -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); diff --git a/app/views/layouts/_ae_resolve_options.html.haml b/app/views/layouts/_ae_resolve_options.html.haml index 5e1a55a5cb57..c9405152e938 100644 --- a/app/views/layouts/_ae_resolve_options.html.haml +++ b/app/views/layouts/_ae_resolve_options.html.haml @@ -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, + :attribute_values_pairs => ApplicationController::AE_MAX_RESOLUTION_FIELDS.times, + :maxlength => ViewHelper::MAX_NAME_LEN, + :submit_url => url) diff --git a/app/views/miq_ae_tools/_resolve_form.html.haml b/app/views/miq_ae_tools/_resolve_form.html.haml index 6556e0352ad9..2daa96defd7d 100644 --- a/app/views/miq_ae_tools/_resolve_form.html.haml +++ b/app/views/miq_ae_tools/_resolve_form.html.haml @@ -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",