mirror of
https://github.com/ansible/awx.git
synced 2026-03-05 18:51:06 -03:30
Merge pull request #144 from keithjgrant/120-add-org-form-cleanup
Refactor org add/edit forms with Formik
This commit is contained in:
84
src/pages/Organizations/components/InstanceGroupsLookup.jsx
Normal file
84
src/pages/Organizations/components/InstanceGroupsLookup.jsx
Normal file
@@ -0,0 +1,84 @@
|
||||
import React, { Fragment } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { I18n, i18nMark } from '@lingui/react';
|
||||
import { FormGroup, Tooltip } from '@patternfly/react-core';
|
||||
import { QuestionCircleIcon } from '@patternfly/react-icons';
|
||||
import { t } from '@lingui/macro';
|
||||
|
||||
import Lookup from '../../../components/Lookup';
|
||||
|
||||
const INSTANCE_GROUPS_LOOKUP_COLUMNS = [
|
||||
{ name: i18nMark('Name'), key: 'name', isSortable: true },
|
||||
{ name: i18nMark('Modified'), key: 'modified', isSortable: false, isNumeric: true },
|
||||
{ name: i18nMark('Created'), key: 'created', isSortable: false, isNumeric: true }
|
||||
];
|
||||
|
||||
class InstanceGroupsLookup extends React.Component {
|
||||
constructor (props) {
|
||||
super(props);
|
||||
|
||||
this.getInstanceGroups = this.getInstanceGroups.bind(this);
|
||||
}
|
||||
|
||||
async getInstanceGroups (params) {
|
||||
const { api } = this.props;
|
||||
const data = await api.getInstanceGroups(params);
|
||||
return data;
|
||||
}
|
||||
|
||||
render () {
|
||||
const { value, tooltip, onChange } = this.props;
|
||||
|
||||
return (
|
||||
<I18n>
|
||||
{({ i18n }) => (
|
||||
<FormGroup
|
||||
label={(
|
||||
<Fragment>
|
||||
{i18n._(t`Instance Groups`)}
|
||||
{' '}
|
||||
{
|
||||
tooltip && (
|
||||
<Tooltip
|
||||
position="right"
|
||||
content={tooltip}
|
||||
>
|
||||
<QuestionCircleIcon />
|
||||
</Tooltip>
|
||||
)
|
||||
}
|
||||
</Fragment>
|
||||
)}
|
||||
fieldId="org-instance-groups"
|
||||
>
|
||||
<Lookup
|
||||
id="org-instance-groups"
|
||||
lookupHeader={i18n._(t`Instance Groups`)}
|
||||
name="instanceGroups"
|
||||
value={value}
|
||||
onLookupSave={onChange}
|
||||
getItems={this.getInstanceGroups}
|
||||
columns={INSTANCE_GROUPS_LOOKUP_COLUMNS}
|
||||
sortedColumnKey="name"
|
||||
/>
|
||||
</FormGroup>
|
||||
)}
|
||||
</I18n>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
InstanceGroupsLookup.propTypes = {
|
||||
api: PropTypes.shape({
|
||||
getInstanceGroups: PropTypes.func,
|
||||
}).isRequired,
|
||||
value: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||
tooltip: PropTypes.string,
|
||||
onChange: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
InstanceGroupsLookup.defaultProps = {
|
||||
tooltip: '',
|
||||
};
|
||||
|
||||
export default InstanceGroupsLookup;
|
||||
178
src/pages/Organizations/components/OrganizationForm.jsx
Normal file
178
src/pages/Organizations/components/OrganizationForm.jsx
Normal file
@@ -0,0 +1,178 @@
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { withRouter } from 'react-router-dom';
|
||||
import { Formik, Field } from 'formik';
|
||||
import { I18n } from '@lingui/react';
|
||||
import { t } from '@lingui/macro';
|
||||
import {
|
||||
Form,
|
||||
FormGroup,
|
||||
} from '@patternfly/react-core';
|
||||
|
||||
import { ConfigContext } from '../../../context';
|
||||
import FormRow from '../../../components/FormRow';
|
||||
import FormField from '../../../components/FormField';
|
||||
import FormActionGroup from '../../../components/FormActionGroup';
|
||||
import AnsibleSelect from '../../../components/AnsibleSelect';
|
||||
import InstanceGroupsLookup from './InstanceGroupsLookup';
|
||||
import { required } from '../../../util/validators';
|
||||
|
||||
class OrganizationForm extends Component {
|
||||
constructor (props) {
|
||||
super(props);
|
||||
|
||||
this.getRelatedInstanceGroups = this.getRelatedInstanceGroups.bind(this);
|
||||
this.handleInstanceGroupsChange = this.handleInstanceGroupsChange.bind(this);
|
||||
this.handleSubmit = this.handleSubmit.bind(this);
|
||||
|
||||
this.state = {
|
||||
instanceGroups: [],
|
||||
formIsValid: true,
|
||||
};
|
||||
}
|
||||
|
||||
async componentDidMount () {
|
||||
let instanceGroups = [];
|
||||
|
||||
if (!this.isEditingNewOrganization()) {
|
||||
try {
|
||||
instanceGroups = await this.getRelatedInstanceGroups();
|
||||
} catch (err) {
|
||||
this.setState({ error: err });
|
||||
}
|
||||
}
|
||||
|
||||
this.setState({
|
||||
instanceGroups,
|
||||
initialInstanceGroups: [...instanceGroups],
|
||||
});
|
||||
}
|
||||
|
||||
async getRelatedInstanceGroups () {
|
||||
const {
|
||||
api,
|
||||
organization: { id }
|
||||
} = this.props;
|
||||
const { data } = await api.getOrganizationInstanceGroups(id);
|
||||
return data.results;
|
||||
}
|
||||
|
||||
isEditingNewOrganization () {
|
||||
const { organization } = this.props;
|
||||
return !organization.id;
|
||||
}
|
||||
|
||||
handleInstanceGroupsChange (instanceGroups) {
|
||||
this.setState({ instanceGroups });
|
||||
}
|
||||
|
||||
handleSubmit (values) {
|
||||
const { handleSubmit } = this.props;
|
||||
const { instanceGroups, initialInstanceGroups } = this.state;
|
||||
|
||||
const initialIds = initialInstanceGroups.map(ig => ig.id);
|
||||
const updatedIds = instanceGroups.map(ig => ig.id);
|
||||
const groupsToAssociate = [...updatedIds]
|
||||
.filter(x => !initialIds.includes(x));
|
||||
const groupsToDisassociate = [...initialIds]
|
||||
.filter(x => !updatedIds.includes(x));
|
||||
|
||||
handleSubmit(values, groupsToAssociate, groupsToDisassociate);
|
||||
}
|
||||
|
||||
render () {
|
||||
const { api, organization, handleCancel } = this.props;
|
||||
const { instanceGroups, formIsValid, error } = this.state;
|
||||
const defaultVenv = '/venv/ansible/';
|
||||
|
||||
return (
|
||||
<I18n>
|
||||
{({ i18n }) => (
|
||||
<Formik
|
||||
initialValues={{
|
||||
name: organization.name,
|
||||
description: organization.description,
|
||||
custom_virtualenv: organization.custom_virtualenv || '',
|
||||
}}
|
||||
onSubmit={this.handleSubmit}
|
||||
render={formik => (
|
||||
<Form autoComplete="off" onSubmit={formik.handleSubmit}>
|
||||
<FormRow>
|
||||
<FormField
|
||||
id="org-name"
|
||||
name="name"
|
||||
type="text"
|
||||
label={i18n._(t`Name`)}
|
||||
validate={required()}
|
||||
isRequired
|
||||
/>
|
||||
<FormField
|
||||
id="org-description"
|
||||
name="description"
|
||||
type="text"
|
||||
label={i18n._(t`Description`)}
|
||||
/>
|
||||
<ConfigContext.Consumer>
|
||||
{({ custom_virtualenvs }) => (
|
||||
custom_virtualenvs && custom_virtualenvs.length > 1 && (
|
||||
<Field
|
||||
name="custom_virtualenv"
|
||||
render={({ field }) => (
|
||||
<FormGroup
|
||||
fieldId="org-custom-virtualenv"
|
||||
label={i18n._(t`Ansible Environment`)}
|
||||
>
|
||||
<AnsibleSelect
|
||||
data={custom_virtualenvs}
|
||||
defaultSelected={defaultVenv}
|
||||
label={i18n._(t`Ansible Environment`)}
|
||||
{...field}
|
||||
/>
|
||||
</FormGroup>
|
||||
)}
|
||||
/>
|
||||
)
|
||||
)}
|
||||
</ConfigContext.Consumer>
|
||||
</FormRow>
|
||||
<InstanceGroupsLookup
|
||||
api={api}
|
||||
value={instanceGroups}
|
||||
onChange={this.handleInstanceGroupsChange}
|
||||
tooltip={i18n._(t`Select the Instance Groups for this Organization to run on.`)}
|
||||
/>
|
||||
<FormActionGroup
|
||||
onCancel={handleCancel}
|
||||
onSubmit={formik.handleSubmit}
|
||||
submitDisabled={!formIsValid}
|
||||
/>
|
||||
{error ? <div>error</div> : null}
|
||||
</Form>
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
</I18n>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
OrganizationForm.propTypes = {
|
||||
api: PropTypes.shape().isRequired,
|
||||
organization: PropTypes.shape(),
|
||||
handleSubmit: PropTypes.func.isRequired,
|
||||
handleCancel: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
OrganizationForm.defaultProps = {
|
||||
organization: {
|
||||
name: '',
|
||||
description: '',
|
||||
custom_virtualenv: '',
|
||||
}
|
||||
};
|
||||
|
||||
OrganizationForm.contextTypes = {
|
||||
custom_virtualenvs: PropTypes.arrayOf(PropTypes.string)
|
||||
};
|
||||
|
||||
export default withRouter(OrganizationForm);
|
||||
Reference in New Issue
Block a user