mirror of
https://github.com/ansible/awx.git
synced 2026-02-26 23:46:05 -03:30
Reapply prompt on launch for job template fields after rebasing.
This commit is contained in:
@@ -1,82 +1,12 @@
|
|||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import { string, bool } from 'prop-types';
|
import { string, bool } from 'prop-types';
|
||||||
import { useField } from 'formik';
|
|
||||||
import { Split, SplitItem } from '@patternfly/react-core';
|
|
||||||
import { yamlToJson, jsonToYaml, isJson } from '@util/yaml';
|
|
||||||
import CodeMirrorInput from './CodeMirrorInput';
|
|
||||||
import YamlJsonToggle from './YamlJsonToggle';
|
|
||||||
import { JSON_MODE, YAML_MODE } from './constants';
|
|
||||||
|
|
||||||
function VariablesField({ id, name, label, readOnly }) {
|
|
||||||
const [field, meta, helpers] = useField(name);
|
|
||||||
const [mode, setMode] = useState(isJson(field.value) ? JSON_MODE : YAML_MODE);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Split gutter="sm">
|
|
||||||
<SplitItem>
|
|
||||||
<label htmlFor={id} className="pf-c-form__label">
|
|
||||||
<span className="pf-c-form__label-text">{label}</span>
|
|
||||||
</label>
|
|
||||||
</SplitItem>
|
|
||||||
<SplitItem>
|
|
||||||
<YamlJsonToggle
|
|
||||||
mode={mode}
|
|
||||||
onChange={newMode => {
|
|
||||||
try {
|
|
||||||
const newVal =
|
|
||||||
newMode === YAML_MODE
|
|
||||||
? jsonToYaml(field.value)
|
|
||||||
: yamlToJson(field.value);
|
|
||||||
helpers.setValue(newVal);
|
|
||||||
setMode(newMode);
|
|
||||||
} catch (err) {
|
|
||||||
helpers.setError(err.message);
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</SplitItem>
|
|
||||||
</Split>
|
|
||||||
<CodeMirrorInput
|
|
||||||
mode={mode}
|
|
||||||
readOnly={readOnly}
|
|
||||||
{...field}
|
|
||||||
onChange={newVal => {
|
|
||||||
helpers.setValue(newVal);
|
|
||||||
}}
|
|
||||||
hasErrors={!!meta.error}
|
|
||||||
/>
|
|
||||||
{meta.error ? (
|
|
||||||
<div className="pf-c-form__helper-text pf-m-error" aria-live="polite">
|
|
||||||
{meta.error}
|
|
||||||
</div>
|
|
||||||
) : null}
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
VariablesField.propTypes = {
|
|
||||||
id: string.isRequired,
|
|
||||||
name: string.isRequired,
|
|
||||||
label: string.isRequired,
|
|
||||||
readOnly: bool,
|
|
||||||
};
|
|
||||||
VariablesField.defaultProps = {
|
|
||||||
readOnly: false,
|
|
||||||
};
|
|
||||||
|
|
||||||
export default VariablesField;
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
import React, { useState } from 'react';
|
|
||||||
import { string, bool } from 'prop-types';
|
|
||||||
import { withI18n } from '@lingui/react';
|
import { withI18n } from '@lingui/react';
|
||||||
import { t } from '@lingui/macro';
|
import { t } from '@lingui/macro';
|
||||||
import { Field, useFormikContext } from 'formik';
|
import { useField } from 'formik';
|
||||||
import { Split, SplitItem } from '@patternfly/react-core';
|
|
||||||
import { yamlToJson, jsonToYaml, isJson } from '@util/yaml';
|
|
||||||
import { CheckboxField } from '@components/FormField';
|
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
|
import { Split, SplitItem } from '@patternfly/react-core';
|
||||||
|
import { CheckboxField } from '@components/FormField';
|
||||||
|
import { yamlToJson, jsonToYaml, isJson } from '@util/yaml';
|
||||||
import CodeMirrorInput from './CodeMirrorInput';
|
import CodeMirrorInput from './CodeMirrorInput';
|
||||||
import YamlJsonToggle from './YamlJsonToggle';
|
import YamlJsonToggle from './YamlJsonToggle';
|
||||||
import { JSON_MODE, YAML_MODE } from './constants';
|
import { JSON_MODE, YAML_MODE } from './constants';
|
||||||
@@ -91,9 +21,8 @@ const StyledCheckboxField = styled(CheckboxField)`
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
function VariablesField({ i18n, id, name, label, readOnly, promptId }) {
|
function VariablesField({ i18n, id, name, label, readOnly, promptId }) {
|
||||||
const { values, setFieldError, setFieldValue } = useFormikContext();
|
const [field, meta, helpers] = useField(name);
|
||||||
const value = values[name];
|
const [mode, setMode] = useState(isJson(field.value) ? JSON_MODE : YAML_MODE);
|
||||||
const [mode, setMode] = useState(isJson(value) ? JSON_MODE : YAML_MODE);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="pf-c-form__group">
|
<div className="pf-c-form__group">
|
||||||
@@ -111,12 +40,12 @@ function VariablesField({ i18n, id, name, label, readOnly, promptId }) {
|
|||||||
try {
|
try {
|
||||||
const newVal =
|
const newVal =
|
||||||
newMode === YAML_MODE
|
newMode === YAML_MODE
|
||||||
? jsonToYaml(value)
|
? jsonToYaml(field.value)
|
||||||
: yamlToJson(value);
|
: yamlToJson(field.value);
|
||||||
setFieldValue(name, newVal);
|
helpers.setValue(newVal);
|
||||||
setMode(newMode);
|
setMode(newMode);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
setFieldError(name, err.message);
|
helpers.setError(err.message);
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
@@ -130,29 +59,20 @@ function VariablesField({ i18n, id, name, label, readOnly, promptId }) {
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</FieldHeader>
|
</FieldHeader>
|
||||||
<Field name={name}>
|
<CodeMirrorInput
|
||||||
{({ field, form }) => (
|
mode={mode}
|
||||||
<>
|
readOnly={readOnly}
|
||||||
<CodeMirrorInput
|
{...field}
|
||||||
mode={mode}
|
onChange={newVal => {
|
||||||
readOnly={readOnly}
|
helpers.setValue(newVal);
|
||||||
{...field}
|
}}
|
||||||
onChange={newVal => {
|
hasErrors={!!meta.error}
|
||||||
form.setFieldValue(name, newVal);
|
/>
|
||||||
}}
|
{meta.error ? (
|
||||||
hasErrors={!!form.errors[field.name]}
|
<div className="pf-c-form__helper-text pf-m-error" aria-live="polite">
|
||||||
/>
|
{meta.error}
|
||||||
{form.errors[field.name] ? (
|
</div>
|
||||||
<div
|
) : null}
|
||||||
className="pf-c-form__helper-text pf-m-error"
|
|
||||||
aria-live="polite"
|
|
||||||
>
|
|
||||||
{form.errors[field.name]}
|
|
||||||
</div>
|
|
||||||
) : null}
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</Field>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -161,10 +81,11 @@ VariablesField.propTypes = {
|
|||||||
name: string.isRequired,
|
name: string.isRequired,
|
||||||
label: string.isRequired,
|
label: string.isRequired,
|
||||||
readOnly: bool,
|
readOnly: bool,
|
||||||
|
promptId: string,
|
||||||
};
|
};
|
||||||
VariablesField.defaultProps = {
|
VariablesField.defaultProps = {
|
||||||
readOnly: false,
|
readOnly: false,
|
||||||
|
promptId: null,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default withI18n()(VariablesField);
|
export default withI18n()(VariablesField);
|
||||||
*/
|
|
||||||
|
|||||||
@@ -3,210 +3,10 @@ import { withRouter } from 'react-router-dom';
|
|||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { withI18n } from '@lingui/react';
|
import { withI18n } from '@lingui/react';
|
||||||
import { t } from '@lingui/macro';
|
import { t } from '@lingui/macro';
|
||||||
import { FormGroup, ToolbarItem } from '@patternfly/react-core';
|
|
||||||
import { CredentialsAPI, CredentialTypesAPI } from '@api';
|
|
||||||
import AnsibleSelect from '@components/AnsibleSelect';
|
|
||||||
import { FieldTooltip } from '@components/FormField';
|
|
||||||
import CredentialChip from '@components/CredentialChip';
|
|
||||||
import { getQSConfig, parseQueryString } from '@util/qs';
|
|
||||||
import Lookup from './Lookup';
|
|
||||||
import OptionsList from './shared/OptionsList';
|
|
||||||
|
|
||||||
const QS_CONFIG = getQSConfig('credentials', {
|
|
||||||
page: 1,
|
|
||||||
page_size: 5,
|
|
||||||
order_by: 'name',
|
|
||||||
});
|
|
||||||
|
|
||||||
async function loadCredentialTypes() {
|
|
||||||
const { data } = await CredentialTypesAPI.read();
|
|
||||||
const acceptableTypes = ['machine', 'cloud', 'net', 'ssh', 'vault'];
|
|
||||||
return data.results.filter(type => acceptableTypes.includes(type.kind));
|
|
||||||
}
|
|
||||||
|
|
||||||
async function loadCredentials(params, selectedCredentialTypeId) {
|
|
||||||
params.credential_type = selectedCredentialTypeId || 1;
|
|
||||||
const { data } = await CredentialsAPI.read(params);
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
function MultiCredentialsLookup(props) {
|
|
||||||
const { tooltip, value, onChange, onError, history, i18n } = props;
|
|
||||||
const [credentialTypes, setCredentialTypes] = useState([]);
|
|
||||||
const [selectedType, setSelectedType] = useState(null);
|
|
||||||
const [credentials, setCredentials] = useState([]);
|
|
||||||
const [credentialsCount, setCredentialsCount] = useState(0);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
(async () => {
|
|
||||||
try {
|
|
||||||
const types = await loadCredentialTypes();
|
|
||||||
setCredentialTypes(types);
|
|
||||||
const match = types.find(type => type.kind === 'ssh') || types[0];
|
|
||||||
setSelectedType(match);
|
|
||||||
} catch (err) {
|
|
||||||
onError(err);
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
}, [onError]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
(async () => {
|
|
||||||
if (!selectedType) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
const params = parseQueryString(QS_CONFIG, history.location.search);
|
|
||||||
const { results, count } = await loadCredentials(
|
|
||||||
params,
|
|
||||||
selectedType.id
|
|
||||||
);
|
|
||||||
setCredentials(results);
|
|
||||||
setCredentialsCount(count);
|
|
||||||
} catch (err) {
|
|
||||||
onError(err);
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
}, [selectedType, history.location.search, onError]);
|
|
||||||
|
|
||||||
const renderChip = ({ item, removeItem, canDelete }) => (
|
|
||||||
<CredentialChip
|
|
||||||
key={item.id}
|
|
||||||
onClick={() => removeItem(item)}
|
|
||||||
isReadOnly={!canDelete}
|
|
||||||
credential={item}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
|
|
||||||
const isMultiple = selectedType && selectedType.kind === 'vault';
|
|
||||||
|
|
||||||
return (
|
|
||||||
<FormGroup label={i18n._(t`Credentials`)} fieldId="multiCredential">
|
|
||||||
{tooltip && <FieldTooltip content={tooltip} />}
|
|
||||||
<Lookup
|
|
||||||
id="multiCredential"
|
|
||||||
header={i18n._(t`Credentials`)}
|
|
||||||
value={value}
|
|
||||||
multiple
|
|
||||||
onChange={onChange}
|
|
||||||
qsConfig={QS_CONFIG}
|
|
||||||
renderItemChip={renderChip}
|
|
||||||
renderOptionsList={({ state, dispatch, canDelete }) => {
|
|
||||||
return (
|
|
||||||
<Fragment>
|
|
||||||
{credentialTypes && credentialTypes.length > 0 && (
|
|
||||||
<ToolbarItem css=" display: flex; align-items: center;">
|
|
||||||
<div css="flex: 0 0 25%; margin-right: 32px">
|
|
||||||
{i18n._(t`Selected Category`)}
|
|
||||||
</div>
|
|
||||||
<AnsibleSelect
|
|
||||||
css="flex: 1 1 75%;"
|
|
||||||
id="multiCredentialsLookUp-select"
|
|
||||||
label={i18n._(t`Selected Category`)}
|
|
||||||
data={credentialTypes.map(type => ({
|
|
||||||
key: type.id,
|
|
||||||
value: type.id,
|
|
||||||
label: type.name,
|
|
||||||
isDisabled: false,
|
|
||||||
}))}
|
|
||||||
value={selectedType && selectedType.id}
|
|
||||||
onChange={(e, id) => {
|
|
||||||
setSelectedType(
|
|
||||||
credentialTypes.find(o => o.id === parseInt(id, 10))
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</ToolbarItem>
|
|
||||||
)}
|
|
||||||
<OptionsList
|
|
||||||
value={state.selectedItems}
|
|
||||||
options={credentials}
|
|
||||||
optionCount={credentialsCount}
|
|
||||||
searchColumns={[
|
|
||||||
{
|
|
||||||
name: i18n._(t`Name`),
|
|
||||||
key: 'name',
|
|
||||||
isDefault: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: i18n._(t`Created By (Username)`),
|
|
||||||
key: 'created_by__username',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: i18n._(t`Modified By (Username)`),
|
|
||||||
key: 'modified_by__username',
|
|
||||||
},
|
|
||||||
]}
|
|
||||||
sortColumns={[
|
|
||||||
{
|
|
||||||
name: i18n._(t`Name`),
|
|
||||||
key: 'name',
|
|
||||||
},
|
|
||||||
]}
|
|
||||||
multiple={isMultiple}
|
|
||||||
header={i18n._(t`Credentials`)}
|
|
||||||
name="credentials"
|
|
||||||
qsConfig={QS_CONFIG}
|
|
||||||
readOnly={!canDelete}
|
|
||||||
selectItem={item => {
|
|
||||||
if (isMultiple) {
|
|
||||||
return dispatch({ type: 'SELECT_ITEM', item });
|
|
||||||
}
|
|
||||||
const selectedItems = state.selectedItems.filter(
|
|
||||||
i => i.kind !== item.kind
|
|
||||||
);
|
|
||||||
selectedItems.push(item);
|
|
||||||
return dispatch({
|
|
||||||
type: 'SET_SELECTED_ITEMS',
|
|
||||||
selectedItems,
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
deselectItem={item => dispatch({ type: 'DESELECT_ITEM', item })}
|
|
||||||
renderItemChip={renderChip}
|
|
||||||
/>
|
|
||||||
</Fragment>
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</FormGroup>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
MultiCredentialsLookup.propTypes = {
|
|
||||||
tooltip: PropTypes.string,
|
|
||||||
value: PropTypes.arrayOf(
|
|
||||||
PropTypes.shape({
|
|
||||||
id: PropTypes.number,
|
|
||||||
name: PropTypes.string,
|
|
||||||
description: PropTypes.string,
|
|
||||||
kind: PropTypes.string,
|
|
||||||
clound: PropTypes.bool,
|
|
||||||
})
|
|
||||||
),
|
|
||||||
onChange: PropTypes.func.isRequired,
|
|
||||||
onError: PropTypes.func.isRequired,
|
|
||||||
};
|
|
||||||
|
|
||||||
MultiCredentialsLookup.defaultProps = {
|
|
||||||
tooltip: '',
|
|
||||||
value: [],
|
|
||||||
};
|
|
||||||
|
|
||||||
export { MultiCredentialsLookup as _MultiCredentialsLookup };
|
|
||||||
export default withI18n()(withRouter(MultiCredentialsLookup));
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
import React, { Fragment, useState, useEffect } from 'react';
|
|
||||||
import { withRouter } from 'react-router-dom';
|
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import { withI18n } from '@lingui/react';
|
|
||||||
import { t } from '@lingui/macro';
|
|
||||||
import { ToolbarItem } from '@patternfly/react-core';
|
import { ToolbarItem } from '@patternfly/react-core';
|
||||||
import { CredentialsAPI, CredentialTypesAPI } from '@api';
|
import { CredentialsAPI, CredentialTypesAPI } from '@api';
|
||||||
import AnsibleSelect from '@components/AnsibleSelect';
|
import AnsibleSelect from '@components/AnsibleSelect';
|
||||||
import CredentialChip from '@components/CredentialChip';
|
import CredentialChip from '@components/CredentialChip';
|
||||||
import VerticalSeperator from '@components/VerticalSeparator';
|
|
||||||
import { getQSConfig, parseQueryString } from '@util/qs';
|
import { getQSConfig, parseQueryString } from '@util/qs';
|
||||||
import Lookup from './Lookup';
|
import Lookup from './Lookup';
|
||||||
import OptionsList from './shared/OptionsList';
|
import OptionsList from './shared/OptionsList';
|
||||||
@@ -293,8 +93,9 @@ function MultiCredentialsLookup(props) {
|
|||||||
<Fragment>
|
<Fragment>
|
||||||
{credentialTypes && credentialTypes.length > 0 && (
|
{credentialTypes && credentialTypes.length > 0 && (
|
||||||
<ToolbarItem css=" display: flex; align-items: center;">
|
<ToolbarItem css=" display: flex; align-items: center;">
|
||||||
<div css="flex: 0 0 25%;">{i18n._(t`Selected Category`)}</div>
|
<div css="flex: 0 0 25%; margin-right: 32px">
|
||||||
<VerticalSeperator />
|
{i18n._(t`Selected Category`)}
|
||||||
|
</div>
|
||||||
<AnsibleSelect
|
<AnsibleSelect
|
||||||
css="flex: 1 1 75%;"
|
css="flex: 1 1 75%;"
|
||||||
id="multiCredentialsLookUp-select"
|
id="multiCredentialsLookUp-select"
|
||||||
@@ -387,4 +188,3 @@ MultiCredentialsLookup.defaultProps = {
|
|||||||
|
|
||||||
export { MultiCredentialsLookup as _MultiCredentialsLookup };
|
export { MultiCredentialsLookup as _MultiCredentialsLookup };
|
||||||
export default withI18n()(withRouter(MultiCredentialsLookup));
|
export default withI18n()(withRouter(MultiCredentialsLookup));
|
||||||
*/
|
|
||||||
|
|||||||
@@ -6,9 +6,12 @@ import { Formik, useField } from 'formik';
|
|||||||
import { withI18n } from '@lingui/react';
|
import { withI18n } from '@lingui/react';
|
||||||
import { t } from '@lingui/macro';
|
import { t } from '@lingui/macro';
|
||||||
|
|
||||||
import { Form } from '@patternfly/react-core';
|
import { Form, FormGroup } from '@patternfly/react-core';
|
||||||
|
|
||||||
import FormField, { FormSubmitError } from '@components/FormField';
|
import FormField, {
|
||||||
|
FormSubmitError,
|
||||||
|
FieldTooltip,
|
||||||
|
} from '@components/FormField';
|
||||||
import FormActionGroup from '@components/FormActionGroup/FormActionGroup';
|
import FormActionGroup from '@components/FormActionGroup/FormActionGroup';
|
||||||
import { VariablesField } from '@components/CodeMirrorInput';
|
import { VariablesField } from '@components/CodeMirrorInput';
|
||||||
import { required } from '@util/validators';
|
import { required } from '@util/validators';
|
||||||
@@ -23,7 +26,7 @@ function HostFormFields({ host, i18n }) {
|
|||||||
const hostAddMatch = useRouteMatch('/hosts/add');
|
const hostAddMatch = useRouteMatch('/hosts/add');
|
||||||
const inventoryFieldArr = useField({
|
const inventoryFieldArr = useField({
|
||||||
name: 'inventory',
|
name: 'inventory',
|
||||||
validate: required(i18n._(t`Select aå value for this field`), i18n),
|
validate: required(i18n._(t`Select a value for this field`), i18n),
|
||||||
});
|
});
|
||||||
const inventoryMeta = inventoryFieldArr[1];
|
const inventoryMeta = inventoryFieldArr[1];
|
||||||
const inventoryHelpers = inventoryFieldArr[2];
|
const inventoryHelpers = inventoryFieldArr[2];
|
||||||
@@ -45,22 +48,35 @@ function HostFormFields({ host, i18n }) {
|
|||||||
label={i18n._(t`Description`)}
|
label={i18n._(t`Description`)}
|
||||||
/>
|
/>
|
||||||
{hostAddMatch && (
|
{hostAddMatch && (
|
||||||
<InventoryLookup
|
<FormGroup
|
||||||
value={inventory}
|
label={i18n._(t`Inventory`)}
|
||||||
onBlur={() => inventoryHelpers.setTouched()}
|
isRequired
|
||||||
tooltip={i18n._(
|
fieldId="inventory-lookup"
|
||||||
t`Select the inventory that this host will belong to.`
|
|
||||||
)}
|
|
||||||
isValid={!inventoryMeta.touched || !inventoryMeta.error}
|
isValid={!inventoryMeta.touched || !inventoryMeta.error}
|
||||||
helperTextInvalid={inventoryMeta.error}
|
helperTextInvalid={inventoryMeta.error}
|
||||||
onChange={value => {
|
>
|
||||||
inventoryHelpers.setValuealue(value.id);
|
<FieldTooltip
|
||||||
setInventory(value);
|
content={i18n._(
|
||||||
}}
|
t`Select the inventory that this host will belong to.`
|
||||||
required
|
)}
|
||||||
touched={inventoryMeta.touched}
|
/>
|
||||||
error={inventoryMeta.error}
|
<InventoryLookup
|
||||||
/>
|
value={inventory}
|
||||||
|
onBlur={() => inventoryHelpers.setTouched()}
|
||||||
|
tooltip={i18n._(
|
||||||
|
t`Select the inventory that this host will belong to.`
|
||||||
|
)}
|
||||||
|
isValid={!inventoryMeta.touched || !inventoryMeta.error}
|
||||||
|
helperTextInvalid={inventoryMeta.error}
|
||||||
|
onChange={value => {
|
||||||
|
inventoryHelpers.setValue(value.id);
|
||||||
|
setInventory(value);
|
||||||
|
}}
|
||||||
|
required
|
||||||
|
touched={inventoryMeta.touched}
|
||||||
|
error={inventoryMeta.error}
|
||||||
|
/>
|
||||||
|
</FormGroup>
|
||||||
)}
|
)}
|
||||||
<FormFullWidthLayout>
|
<FormFullWidthLayout>
|
||||||
<VariablesField
|
<VariablesField
|
||||||
@@ -122,139 +138,3 @@ HostForm.defaultProps = {
|
|||||||
|
|
||||||
export { HostForm as _HostForm };
|
export { HostForm as _HostForm };
|
||||||
export default withI18n()(HostForm);
|
export default withI18n()(HostForm);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
import React, { useState } from 'react';
|
|
||||||
import { func, shape } from 'prop-types';
|
|
||||||
|
|
||||||
import { useRouteMatch } from 'react-router-dom';
|
|
||||||
import { Formik, Field } from 'formik';
|
|
||||||
import { withI18n } from '@lingui/react';
|
|
||||||
import { t } from '@lingui/macro';
|
|
||||||
|
|
||||||
import { Form, FormGroup } from '@patternfly/react-core';
|
|
||||||
|
|
||||||
import FormRow from '@components/FormRow';
|
|
||||||
import FormField, {
|
|
||||||
FormSubmitError,
|
|
||||||
FieldTooltip,
|
|
||||||
} from '@components/FormField';
|
|
||||||
import FormActionGroup from '@components/FormActionGroup/FormActionGroup';
|
|
||||||
import { VariablesField } from '@components/CodeMirrorInput';
|
|
||||||
import { required } from '@util/validators';
|
|
||||||
import { InventoryLookup } from '@components/Lookup';
|
|
||||||
|
|
||||||
function HostForm({ handleSubmit, handleCancel, host, submitError, i18n }) {
|
|
||||||
const [inventory, setInventory] = useState(
|
|
||||||
host ? host.summary_fields.inventory : ''
|
|
||||||
);
|
|
||||||
|
|
||||||
const hostAddMatch = useRouteMatch('/hosts/add');
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Formik
|
|
||||||
initialValues={{
|
|
||||||
name: host.name,
|
|
||||||
description: host.description,
|
|
||||||
inventory: host.inventory || '',
|
|
||||||
variables: host.variables,
|
|
||||||
}}
|
|
||||||
onSubmit={handleSubmit}
|
|
||||||
>
|
|
||||||
{formik => (
|
|
||||||
<Form autoComplete="off" onSubmit={formik.handleSubmit}>
|
|
||||||
<FormRow>
|
|
||||||
<FormField
|
|
||||||
id="host-name"
|
|
||||||
name="name"
|
|
||||||
type="text"
|
|
||||||
label={i18n._(t`Name`)}
|
|
||||||
validate={required(null, i18n)}
|
|
||||||
isRequired
|
|
||||||
/>
|
|
||||||
<FormField
|
|
||||||
id="host-description"
|
|
||||||
name="description"
|
|
||||||
type="text"
|
|
||||||
label={i18n._(t`Description`)}
|
|
||||||
/>
|
|
||||||
{hostAddMatch && (
|
|
||||||
<Field
|
|
||||||
name="inventory"
|
|
||||||
validate={required(
|
|
||||||
i18n._(t`Select a value for this field`),
|
|
||||||
i18n
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
{({ form }) => (
|
|
||||||
<FormGroup
|
|
||||||
label={i18n._(t`Inventory`)}
|
|
||||||
isRequired
|
|
||||||
fieldId="inventory-lookup"
|
|
||||||
isValid={!form.touched.inventory || !form.errors.inventory}
|
|
||||||
helperTextInvalid={form.errors.inventory}
|
|
||||||
>
|
|
||||||
<FieldTooltip
|
|
||||||
content={i18n._(
|
|
||||||
t`Select the inventory that this host will belong to.`
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
<InventoryLookup
|
|
||||||
value={inventory}
|
|
||||||
onBlur={() => form.setFieldTouched('inventory')}
|
|
||||||
onChange={value => {
|
|
||||||
form.setFieldValue('inventory', value.id);
|
|
||||||
setInventory(value);
|
|
||||||
}}
|
|
||||||
required
|
|
||||||
touched={form.touched.inventory}
|
|
||||||
error={form.errors.inventory}
|
|
||||||
/>
|
|
||||||
</FormGroup>
|
|
||||||
)}
|
|
||||||
</Field>
|
|
||||||
)}
|
|
||||||
</FormRow>
|
|
||||||
<FormRow>
|
|
||||||
<VariablesField
|
|
||||||
id="host-variables"
|
|
||||||
name="variables"
|
|
||||||
label={i18n._(t`Variables`)}
|
|
||||||
/>
|
|
||||||
</FormRow>
|
|
||||||
<FormSubmitError error={submitError} />
|
|
||||||
<FormActionGroup
|
|
||||||
onCancel={handleCancel}
|
|
||||||
onSubmit={formik.handleSubmit}
|
|
||||||
/>
|
|
||||||
</Form>
|
|
||||||
)}
|
|
||||||
</Formik>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
HostForm.propTypes = {
|
|
||||||
handleSubmit: func.isRequired,
|
|
||||||
handleCancel: func.isRequired,
|
|
||||||
host: shape({}),
|
|
||||||
submitError: shape({}),
|
|
||||||
};
|
|
||||||
|
|
||||||
HostForm.defaultProps = {
|
|
||||||
host: {
|
|
||||||
name: '',
|
|
||||||
description: '',
|
|
||||||
inventory: undefined,
|
|
||||||
variables: '---\n',
|
|
||||||
summary_fields: {
|
|
||||||
inventory: null,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
submitError: null,
|
|
||||||
};
|
|
||||||
|
|
||||||
export { HostForm as _HostForm };
|
|
||||||
export default withI18n()(HostForm);
|
|
||||||
*/
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user