import React, { useState } from 'react'
import PropTypes from 'prop-types';
import {
Icon,
Button,
MessageDialog,
} from 'patternfly-react';
import * as resolve from 'table-resolver';
import ForemanModal from 'foremanReact/components/ForemanModal';
import {
sprintf,
translate as __
} from 'foremanReact/common/I18n';
import Select from 'foremanReact/components/common/forms/Select';
import ParameterSelection from '../ParameterSelection';
import ExistingHostSelection from '../ExistingHostSelection';
import AddTableEntry from '../common/AddTableEntry';
import DeleteTableEntry from '../common/DeleteTableEntry';
import RailsData from '../common/RailsData';
import AppDefinitionSelector from './components/AppDefinitionSelector';
import ServiceCounter from './components/ServiceCounter';
import { arrayToObject } from '../../helper';
import { EasyHeaderFormatter } from '../../helper';
import {
Table,
FormControl,
inlineEditFormatterFactory,
} from 'patternfly-react';
import {
PARAMETER_SELECTION_PARAM_TYPE_FOREMAN,
PARAMETER_SELECTION_PARAM_TYPE_ANSIBLE,
} from '../ParameterSelection/ParameterSelectionConstants';
class ApplicationInstance extends React.Component {
constructor(props) {
super(props);
}
isEditing({rowData}) {
return (rowData.backup !== undefined);
}
changeDataAllowed() {
return this.props.editMode || this.props.appDefinition.id == ''
}
validateParameters() {
let result = true;
let msg = "";
this.props.hosts.forEach(h => {
if (h.foremanParameters.map(e => e.value).filter(i => i == "").length > 0) {
result = false;
if (msg == "") {
msg += __("For some hosts the values for some parameters are missing. Check the values for these hosts:\n");
}
msg += "- "+ h.hostname +"\n";
}
});
const invalidMinServices = this.props.services.filter(s => (Number(s.minCount) != 0) && (s.currentCount < s.minCount));
const invalidMaxServices = this.props.services.filter(s => (Number(s.maxCount) != 0) && (s.currentCount > s.maxCount));
if (invalidMinServices.length > 0 || invalidMaxServices.length > 0) {
result = false;
if (msg != "") {
msg += "\n";
}
msg += __("Unachieved service counts:");
msg += "\n";
invalidMinServices.map(s => { msg += sprintf(
__(`- service ${s.name} expects at ${s.minCount} least configured hosts\n`)
)});
invalidMaxServices.map(s => { msg += sprintf(
__(`- service ${s.name} expects no more than ${s.axCount} configured hosts\n`)
)});
}
return {
validateResult: result,
validateMsg: msg
}
}
componentDidMount() {
const {
data: { mode, appDefinition, hosts, ansibleVarsAll, appDefinitionUrl, supportedPlugins },
initApplicationInstance,
addApplicationInstanceHost,
deleteApplicationInstanceHost,
activateEditApplicationInstanceHost,
changeEditApplicationInstanceHost,
openForemanParameterSelectionModal,
openAnsibleParameterSelectionModal,
loadApplicationDefinition,
} = this.props;
if (mode === 'editInstance') {
loadApplicationDefinition(appDefinition.id, { url: appDefinitionUrl });
}
const already_deployed_msg = __("This is an already deployed host. Changing the parameters is not possible!");
const inlineEditButtonsFormatter = inlineEditFormatterFactory({
isEditing: additionalData => this.props.editMode,
renderValue: (value, additionalData) => (
{ additionalData.rowData.isExistingHost == true ? (
) : ()}
{ additionalData.rowData.isExistingHost == false ? (
) : ()}
|
),
renderEdit: (value, additionalData) => (
{ additionalData.rowData.isExistingHost == true ? (
) : ()}
{ additionalData.rowData.isExistingHost == false ? (
) : ()}
|
)
});
this.inlineEditButtonsFormatter = inlineEditButtonsFormatter;
this.headerFormatter = EasyHeaderFormatter;
const inlineEditFormatterImpl = {
renderValue: (value, additionalData) => (
{value}
|
),
renderEditText: (value, additionalData, subtype='text') => (
changeEditApplicationInstanceHost(e.target.value, additionalData) }
/>
|
),
renderEditSelect: (value, additionalData, options) => (
|
)
};
const inlineEditFormatter = inlineEditFormatterFactory({
isEditing: additionalData => this.isEditing(additionalData),
renderValue: (value, additionalData) => {
let prettyValue = value;
if (additionalData.property == 'service') {
const serviceList = arrayToObject(this.props.services, "id", "name");
prettyValue = serviceList[value];
}
return inlineEditFormatterImpl.renderValue(prettyValue, additionalData)
},
renderEdit: (value, additionalData) => {
let prettyValue = value;
if (additionalData.property == 'service') {
const availableServices = this.props.services.filter(service => ((Number(service['maxCount']) == 0) || (service['currentCount'] < service['maxCount'])));
const serviceList = arrayToObject(availableServices, "id", "name");
if (additionalData.rowData.newEntry === true) {
return inlineEditFormatterImpl.renderEditSelect(value, additionalData, serviceList);
}
prettyValue = serviceList[value];
return inlineEditFormatterImpl.renderValue(prettyValue, additionalData)
}
if (additionalData.property == 'hostname') {
if (additionalData.rowData.newEntry === true) {
return inlineEditFormatterImpl.renderEditText(value, additionalData);
}
return inlineEditFormatterImpl.renderValue(prettyValue, additionalData)
}
return inlineEditFormatterImpl.renderEditText(prettyValue, additionalData);
}
});
this.inlineEditFormatter = inlineEditFormatter;
initApplicationInstance(
appDefinition,
hosts,
ansibleVarsAll,
supportedPlugins,
this.headerFormatter,
this.inlineEditFormatter,
this.inlineEditButtonsFormatter,
);
};
render() {
const {
data: { mode, applications, organization, location, foremanDataUrl, appDefinitionUrl },
showAlertModal, alertModalText, alertModalTitle, closeAlertModal,
appDefinition,
services,
hosts,
columns,
hiddenForemanParameterTypes,
addApplicationInstanceHost,
confirmEditApplicationInstanceHost,
cancelEditApplicationInstanceHost,
closeForemanParameterSelectionModal,
openAnsibleParameterSelectionModal,
closeAnsibleParameterSelectionModal,
openAddExistingHostsModal,
closeAddExistingHostsModal,
changeParameterSelectionMode,
loadApplicationDefinition,
} = this.props;
let { validateResult, validateMsg } = this.validateParameters();
if (validateResult == false) {
$('input[type="submit"][name="commit"]').attr("disabled", true);
} else {
$('input[type="submit"][name="commit"]').attr("disabled", false);
}
return (
}
title={alertModalTitle}
primaryContent={alertModalText}
/>
{appDefinition.id == '' ? (
{ "App Definition can't be blank" }
) : (
)}
cellProps.children
}
}}
>
({
role: 'row',
isEditing: () => this.isEditing({ rowData }),
onCancel: () => cancelEditApplicationInstanceHost({ rowData, rowIndex }),
onConfirm: () => confirmEditApplicationInstanceHost({ rowData, rowIndex, appDefinition }),
last: rowIndex === services.length - 1
})}
/>
Ansible group vars 'all':
{__("Parameter specification")}
{this.props.parametersData ? (
changeParameterSelectionMode({ mode: hide })}
paramType={ PARAMETER_SELECTION_PARAM_TYPE_FOREMAN }
hiddenParameterTypes={ hiddenForemanParameterTypes }
location={ location }
organization={ organization }
paramDataUrl= { foremanDataUrl }
data={ this.props.parametersData }
/>
) : (Empty)
}
{__("Parameter specification")}
{this.props.parametersData ? (
changeParameterSelectionMode({ mode: hide })}
paramType={ PARAMETER_SELECTION_PARAM_TYPE_ANSIBLE }
location={ location }
organization={ organization }
data={ this.props.parametersData }
/>
) : (Empty)
}
{__("Existing hosts selection")}
{validateResult == false ? (
) : ()}
)};
}
ApplicationInstance.defaultProps = {
error: {},
showAlertModal: false,
alertModalText: '',
alertModalTitle: '',
appDefinition: { "id": '', "name": '' },
editMode: false,
services: [],
hosts: [],
ansibleVarsAll: [],
parametersData: {},
columns: [],
hiddenForemanParameterTypes: [],
editParamsOfRowId: null,
paramEditMode: false,
}
ApplicationInstance.propTypes = {
initApplicationInstance: PropTypes.func,
showAlertModal: PropTypes.bool,
alertModalText: PropTypes.string,
alertModalTitle: PropTypes.string,
editMode: PropTypes.bool.isRequired,
services: PropTypes.array,
appDefinition: PropTypes.object,
columns: PropTypes.array,
hiddenForemanParameterTypes: PropTypes.array,
hosts: PropTypes.array,
ansibleVarsAll: PropTypes.array,
closeAlertModal: PropTypes.func,
loadApplicationDefinition: PropTypes.func,
addApplicationInstanceHost: PropTypes.func,
deleteApplicationInstanceHost: PropTypes.func,
activateEditApplicationInstanceHost: PropTypes.func,
confirmEditApplicationInstanceHost: PropTypes.func,
cancelEditApplicationInstanceHost: PropTypes.func,
changeEditApplicationInstanceHost: PropTypes.func,
openForemanParameterSelectionModal: PropTypes.func,
closeForemanParameterSelectionModal: PropTypes.func,
openAnsibleParameterSelectionModal: PropTypes.func,
closeAnsibleParameterSelectionModal: PropTypes.func,
openAddExistingHostsModal: PropTypes.func,
closeAddExistingHostsModal: PropTypes.func,
changeParameterSelectionMode: PropTypes.func,
parametersData: PropTypes.object,
paramEditMode: PropTypes.bool,
};
export default ApplicationInstance;