update forms from FormRow to using FormLayout components

This commit is contained in:
John Mitchell
2020-02-18 14:35:41 -05:00
parent ff823c9fdb
commit df13a8fea9
17 changed files with 655 additions and 608 deletions

View File

@@ -3,6 +3,7 @@ import { string, bool } from 'prop-types';
import { useField } from 'formik'; import { useField } from 'formik';
import { Split, SplitItem } from '@patternfly/react-core'; import { Split, SplitItem } from '@patternfly/react-core';
import { yamlToJson, jsonToYaml, isJson } from '@util/yaml'; import { yamlToJson, jsonToYaml, isJson } from '@util/yaml';
import { FormFullWidthLayout } from '@components/FormLayout';
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';
@@ -12,9 +13,7 @@ function VariablesField({ id, name, label, readOnly }) {
const [mode, setMode] = useState(isJson(field.value) ? JSON_MODE : YAML_MODE); const [mode, setMode] = useState(isJson(field.value) ? JSON_MODE : YAML_MODE);
return ( return (
<Field name={name}> <FormFullWidthLayout>
{({ field, form }) => (
<div className="pf-c-form__group">
<Split gutter="sm"> <Split gutter="sm">
<SplitItem> <SplitItem>
<label htmlFor={id} className="pf-c-form__label"> <label htmlFor={id} className="pf-c-form__label">
@@ -53,9 +52,7 @@ function VariablesField({ id, name, label, readOnly }) {
{meta.error} {meta.error}
</div> </div>
) : null} ) : null}
</div> </FormFullWidthLayout>
)}
</Field>
); );
} }
VariablesField.propTypes = { VariablesField.propTypes = {

View File

@@ -9,6 +9,7 @@ const ActionGroup = styled(PFActionGroup)`
display: flex; display: flex;
justify-content: flex-end; justify-content: flex-end;
--pf-c-form__group--m-action--MarginTop: 0; --pf-c-form__group--m-action--MarginTop: 0;
grid-column: 1 / -1;
.pf-c-form__actions { .pf-c-form__actions {
& > button { & > button {

View File

@@ -0,0 +1,44 @@
import styled from 'styled-components';
export const FormColumnLayout = styled.div`
width: 100%;
grid-column: 1 / 4;
display: grid;
grid-gap: 20px;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
@media (min-width: 1210px) {
grid-template-columns: repeat(3, 1fr);
}
`;
export const FormFullWidthLayout = styled.div`
grid-column: 1 / -1;
display: grid;
grid-template-columns: 1fr;
grid-gap: 20px;
`;
export const FormCheckboxLayout = styled.div`
display: flex;
justify-content: flex-start;
flex-wrap: wrap;
& > * {
margin-right: 30px;
margin-bottom: 10px;
}
`;
export const SubFormLayout = styled.div`
grid-column: 1 / -1;
background-color: #f5f5f5;
margin: 0 -24px;
padding: 24px;
& > .pf-c-title {
--pf-c-title--m-md--FontWeight: 700;
grid-column: 1 / -1;
margin-bottom: 20px;
}
`;

View File

@@ -0,0 +1,6 @@
export {
FormColumnLayout,
FormFullWidthLayout,
FormCheckboxLayout,
SubFormLayout,
} from './FormLayout';

View File

@@ -1,11 +0,0 @@
import React from 'react';
import styled from 'styled-components';
const Row = styled.div`
display: grid;
grid-gap: 20px;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
`;
export default function FormRow({ children, className }) {
return <Row className={className}>{children}</Row>;
}

View File

@@ -1,11 +0,0 @@
import React from 'react';
import { mount } from 'enzyme';
import FormRow from './FormRow';
describe('FormRow', () => {
test('renders the expected content', () => {
const wrapper = mount(<FormRow />);
expect(wrapper).toHaveLength(1);
});
});

View File

@@ -1 +0,0 @@
export { default } from './FormRow';

View File

@@ -8,12 +8,12 @@ import { t } from '@lingui/macro';
import { Form } from '@patternfly/react-core'; import { Form } from '@patternfly/react-core';
import FormRow from '@components/FormRow';
import FormField, { FormSubmitError } from '@components/FormField'; import FormField, { FormSubmitError } 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';
import { InventoryLookup } from '@components/Lookup'; import { InventoryLookup } from '@components/Lookup';
import { FormColumnLayout } from '@components/FormLayout';
function HostFormFields({ host, i18n }) { function HostFormFields({ host, i18n }) {
const [inventory, setInventory] = useState( const [inventory, setInventory] = useState(
@@ -84,12 +84,14 @@ function HostForm({ handleSubmit, host, submitError, handleCancel, ...rest }) {
> >
{formik => ( {formik => (
<Form autoComplete="off" onSubmit={formik.handleSubmit}> <Form autoComplete="off" onSubmit={formik.handleSubmit}>
<FormColumnLayout>
<HostFormFields host={host} {...rest} /> <HostFormFields host={host} {...rest} />
<FormSubmitError error={submitError} /> <FormSubmitError error={submitError} />
<FormActionGroup <FormActionGroup
onCancel={handleCancel} onCancel={handleCancel}
onSubmit={formik.handleSubmit} onSubmit={formik.handleSubmit}
/> />
</FormColumnLayout>
</Form> </Form>
)} )}
</Formik> </Formik>

View File

@@ -12,6 +12,7 @@ import { required } from '@util/validators';
import InstanceGroupsLookup from '@components/Lookup/InstanceGroupsLookup'; import InstanceGroupsLookup from '@components/Lookup/InstanceGroupsLookup';
import OrganizationLookup from '@components/Lookup/OrganizationLookup'; import OrganizationLookup from '@components/Lookup/OrganizationLookup';
import CredentialLookup from '@components/Lookup/CredentialLookup'; import CredentialLookup from '@components/Lookup/CredentialLookup';
import { FormColumnLayout } from '@components/FormLayout';
function InventoryFormFields({ i18n, credentialTypeId }) { function InventoryFormFields({ i18n, credentialTypeId }) {
const [organizationField, organizationMeta, organizationHelpers] = useField({ const [organizationField, organizationMeta, organizationHelpers] = useField({
@@ -108,13 +109,14 @@ function InventoryForm({
> >
{formik => ( {formik => (
<Form autoComplete="off" onSubmit={formik.handleSubmit}> <Form autoComplete="off" onSubmit={formik.handleSubmit}>
<FormColumnLayout>
<InventoryFormFields {...rest} /> <InventoryFormFields {...rest} />
<FormSubmitError error={submitError} /> <FormSubmitError error={submitError} />
<FormActionGroup <FormActionGroup
onCancel={onCancel} onCancel={onCancel}
onSubmit={formik.handleSubmit} onSubmit={formik.handleSubmit}
/> />
</FormRow> </FormColumnLayout>
</Form> </Form>
)} )}
</Formik> </Formik>

View File

@@ -6,11 +6,11 @@ import { Form, Card } from '@patternfly/react-core';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { CardBody } from '@components/Card'; import { CardBody } from '@components/Card';
import FormRow from '@components/FormRow';
import FormField from '@components/FormField'; import FormField 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';
import { FormColumnLayout } from '@components/FormLayout';
function InventoryGroupForm({ function InventoryGroupForm({
i18n, i18n,
@@ -31,7 +31,7 @@ function InventoryGroupForm({
<Formik initialValues={initialValues} onSubmit={handleSubmit}> <Formik initialValues={initialValues} onSubmit={handleSubmit}>
{formik => ( {formik => (
<Form autoComplete="off" onSubmit={formik.handleSubmit}> <Form autoComplete="off" onSubmit={formik.handleSubmit}>
<FormRow css="grid-template-columns: repeat(auto-fit, minmax(300px, 500px));"> <FormColumnLayout>
<FormField <FormField
id="inventoryGroup-name" id="inventoryGroup-name"
name="name" name="name"
@@ -46,19 +46,17 @@ function InventoryGroupForm({
type="text" type="text"
label={i18n._(t`Description`)} label={i18n._(t`Description`)}
/> />
</FormRow>
<FormRow>
<VariablesField <VariablesField
id="host-variables" id="host-variables"
name="variables" name="variables"
label={i18n._(t`Variables`)} label={i18n._(t`Variables`)}
/> />
</FormRow>
<FormActionGroup <FormActionGroup
onCancel={handleCancel} onCancel={handleCancel}
onSubmit={formik.handleSubmit} onSubmit={formik.handleSubmit}
/> />
{error ? <div>error</div> : null} {error ? <div>error</div> : null}
</FormColumnLayout>
</Form> </Form>
)} )}
</Formik> </Formik>

View File

@@ -11,12 +11,12 @@ import { ConfigContext } from '@contexts/Config';
import AnsibleSelect from '@components/AnsibleSelect'; import AnsibleSelect from '@components/AnsibleSelect';
import ContentError from '@components/ContentError'; import ContentError from '@components/ContentError';
import ContentLoading from '@components/ContentLoading'; import ContentLoading from '@components/ContentLoading';
import FormRow from '@components/FormRow';
import FormField, { FormSubmitError } from '@components/FormField'; import FormField, { FormSubmitError } from '@components/FormField';
import FormActionGroup from '@components/FormActionGroup/FormActionGroup'; import FormActionGroup from '@components/FormActionGroup/FormActionGroup';
import { InstanceGroupsLookup } from '@components/Lookup/'; import { InstanceGroupsLookup } from '@components/Lookup/';
import { getAddedAndRemoved } from '@util/lists'; import { getAddedAndRemoved } from '@util/lists';
import { required, minMaxValue } from '@util/validators'; import { required, minMaxValue } from '@util/validators';
import { FormColumnLayout } from '@components/FormLayout';
function OrganizationFormFields({ function OrganizationFormFields({
i18n, i18n,
@@ -166,6 +166,7 @@ function OrganizationForm({
> >
{formik => ( {formik => (
<Form autoComplete="off" onSubmit={formik.handleSubmit}> <Form autoComplete="off" onSubmit={formik.handleSubmit}>
<FormColumnLayout>
<OrganizationFormFields <OrganizationFormFields
instanceGroups={instanceGroups} instanceGroups={instanceGroups}
setInstanceGroups={setInstanceGroups} setInstanceGroups={setInstanceGroups}
@@ -176,6 +177,7 @@ function OrganizationForm({
onCancel={handleCancel} onCancel={handleCancel}
onSubmit={formik.handleSubmit} onSubmit={formik.handleSubmit}
/> />
</FormColumnLayout>
</Form> </Form>
)} )}
</Formik> </Formik>

View File

@@ -14,11 +14,10 @@ import FormField, {
FieldTooltip, FieldTooltip,
FormSubmitError, FormSubmitError,
} from '@components/FormField'; } from '@components/FormField';
import FormRow from '@components/FormRow';
import OrganizationLookup from '@components/Lookup/OrganizationLookup'; import OrganizationLookup from '@components/Lookup/OrganizationLookup';
import { CredentialTypesAPI, ProjectsAPI } from '@api'; import { CredentialTypesAPI, ProjectsAPI } from '@api';
import { required } from '@util/validators'; import { required } from '@util/validators';
import styled from 'styled-components'; import { FormColumnLayout, SubFormLayout } from '@components/FormLayout';
import { import {
GitSubForm, GitSubForm,
HgSubForm, HgSubForm,
@@ -206,10 +205,9 @@ function ProjectFormFields({
/> />
</FormGroup> </FormGroup>
{formik.values.scm_type !== '' && ( {formik.values.scm_type !== '' && (
<ScmTypeFormRow> <SubFormLayout>
<SubFormTitle size="md"> <Title size="md">{i18n._(t`Type Details`)}</Title>
{i18n._(t`Type Details`)} <FormColumnLayout>
</SubFormTitle>
{ {
{ {
manual: ( manual: (
@@ -249,14 +247,13 @@ function ProjectFormFields({
), ),
}[formik.values.scm_type] }[formik.values.scm_type]
} }
</ScmTypeFormRow> </FormColumnLayout>
</SubFormLayout>
)} )}
<Config> <Config>
{({ custom_virtualenvs }) => {({ custom_virtualenvs }) =>
custom_virtualenvs && custom_virtualenvs &&
custom_virtualenvs.length > 1 && ( custom_virtualenvs.length > 1 && (
<Field name="custom_virtualenv">
{({ field }) => (
<FormGroup <FormGroup
fieldId="project-custom-virtualenv" fieldId="project-custom-virtualenv"
label={i18n._(t`Ansible Environment`)} label={i18n._(t`Ansible Environment`)}
@@ -373,6 +370,7 @@ function ProjectForm({ i18n, project, submitError, ...props }) {
onSubmit={formik.handleSubmit} onSubmit={formik.handleSubmit}
css="padding: 0 24px" css="padding: 0 24px"
> >
<FormColumnLayout>
<ProjectFormFields <ProjectFormFields
project_base_dir={project_base_dir} project_base_dir={project_base_dir}
project_local_paths={project_local_paths} project_local_paths={project_local_paths}
@@ -391,6 +389,7 @@ function ProjectForm({ i18n, project, submitError, ...props }) {
onCancel={handleCancel} onCancel={handleCancel}
onSubmit={formik.handleSubmit} onSubmit={formik.handleSubmit}
/> />
</FormColumnLayout>
</Form> </Form>
)} )}
</Formik> </Formik>

View File

@@ -6,12 +6,10 @@ import CredentialLookup from '@components/Lookup/CredentialLookup';
import FormField, { CheckboxField } from '@components/FormField'; import FormField, { CheckboxField } from '@components/FormField';
import { required } from '@util/validators'; import { required } from '@util/validators';
import { FormGroup, Title } from '@patternfly/react-core'; import { FormGroup, Title } from '@patternfly/react-core';
import styled from 'styled-components'; import {
FormCheckboxLayout,
export const SubFormTitle = styled(Title)` FormFullWidthLayout,
--pf-c-title--m-md--FontWeight: 700; } from '@components/FormLayout';
grid-column: 1 / -1;
`;
export const UrlFormField = withI18n()(({ i18n, tooltip }) => ( export const UrlFormField = withI18n()(({ i18n, tooltip }) => (
<FormField <FormField
@@ -59,13 +57,9 @@ export const ScmCredentialFormField = withI18n()(
export const ScmTypeOptions = withI18n()( export const ScmTypeOptions = withI18n()(
({ i18n, scmUpdateOnLaunch, hideAllowOverride }) => ( ({ i18n, scmUpdateOnLaunch, hideAllowOverride }) => (
<> <FormFullWidthLayout>
<FormGroup <FormGroup fieldId="project-option-checkboxes" label={i18n._(t`Options`)}>
css="grid-column: 1/-1" <FormCheckboxLayout>
fieldId="project-option-checkboxes"
label={i18n._(t`Options`)}
>
<FormRow>
<CheckboxField <CheckboxField
id="option-scm-clean" id="option-scm-clean"
name="scm_clean" name="scm_clean"
@@ -105,11 +99,12 @@ export const ScmTypeOptions = withI18n()(
)} )}
/> />
)} )}
</FormRow> </FormCheckboxLayout>
</FormGroup> </FormGroup>
{scmUpdateOnLaunch && ( {scmUpdateOnLaunch && (
<> <>
<SubFormTitle size="md">{i18n._(t`Option Details`)}</SubFormTitle> <Title size="md">{i18n._(t`Option Details`)}</Title>
<FormField <FormField
id="project-cache-timeout" id="project-cache-timeout"
name="scm_update_cache_timeout" name="scm_update_cache_timeout"
@@ -125,6 +120,6 @@ export const ScmTypeOptions = withI18n()(
/> />
</> </>
)} )}
</> </FormFullWidthLayout>
) )
); );

View File

@@ -1,4 +1,3 @@
export { SubFormTitle } from './SharedFields';
export { default as GitSubForm } from './GitSubForm'; export { default as GitSubForm } from './GitSubForm';
export { default as HgSubForm } from './HgSubForm'; export { default as HgSubForm } from './HgSubForm';
export { default as InsightsSubForm } from './InsightsSubForm'; export { default as InsightsSubForm } from './InsightsSubForm';

View File

@@ -8,6 +8,7 @@ import FormActionGroup from '@components/FormActionGroup/FormActionGroup';
import FormField, { FormSubmitError } from '@components/FormField'; import FormField, { FormSubmitError } from '@components/FormField';
import OrganizationLookup from '@components/Lookup/OrganizationLookup'; import OrganizationLookup from '@components/Lookup/OrganizationLookup';
import { required } from '@util/validators'; import { required } from '@util/validators';
import { FormColumnLayout } from '@components/FormLayout';
function TeamFormFields(props) { function TeamFormFields(props) {
const { team, i18n } = props; const { team, i18n } = props;
@@ -68,14 +69,15 @@ function TeamForm(props) {
<Form <Form
autoComplete="off" autoComplete="off"
onSubmit={formik.handleSubmit} onSubmit={formik.handleSubmit}
css="padding: 0 24px"
> >
<FormColumnLayout>
<TeamFormFields team={team} {...rest} /> <TeamFormFields team={team} {...rest} />
<FormSubmitError error={submitError} /> <FormSubmitError error={submitError} />
<FormActionGroup <FormActionGroup
onCancel={handleCancel} onCancel={handleCancel}
onSubmit={formik.handleSubmit} onSubmit={formik.handleSubmit}
/> />
</FormColumnLayout>
</Form> </Form>
)} )}
</Formik> </Formik>

View File

@@ -22,10 +22,13 @@ import FormField, {
FormSubmitError, FormSubmitError,
} from '@components/FormField'; } from '@components/FormField';
import FieldWithPrompt from '@components/FieldWithPrompt'; import FieldWithPrompt from '@components/FieldWithPrompt';
import FormRow from '@components/FormRow'; import {
FormColumnLayout,
FormFullWidthLayout,
FormCheckboxLayout,
} from '@components/FormLayout';
import CollapsibleSection from '@components/CollapsibleSection'; import CollapsibleSection from '@components/CollapsibleSection';
import { required } from '@util/validators'; import { required } from '@util/validators';
import styled from 'styled-components';
import { JobTemplate } from '@types'; import { JobTemplate } from '@types';
import { import {
InventoryLookup, InventoryLookup,
@@ -37,17 +40,6 @@ import { JobTemplatesAPI, ProjectsAPI } from '@api';
import LabelSelect from './LabelSelect'; import LabelSelect from './LabelSelect';
import PlaybookSelect from './PlaybookSelect'; import PlaybookSelect from './PlaybookSelect';
const GridFormGroup = styled(FormGroup)`
& > label {
grid-column: 1 / -1;
}
&& {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
}
`;
class JobTemplateForm extends Component { class JobTemplateForm extends Component {
static propTypes = { static propTypes = {
template: JobTemplate, template: JobTemplate,
@@ -211,9 +203,10 @@ class JobTemplateForm extends Component {
} }
const AdvancedFieldsWrapper = template.isNew ? CollapsibleSection : 'div'; const AdvancedFieldsWrapper = template.isNew ? CollapsibleSection : 'div';
return ( return (
<Form autoComplete="off" onSubmit={handleSubmit}> <Form autoComplete="off" onSubmit={handleSubmit}>
<FormRow> <FormColumnLayout>
<FormField <FormField
id="template-name" id="template-name"
name="name" name="name"
@@ -334,8 +327,7 @@ class JobTemplateForm extends Component {
); );
}} }}
</Field> </Field>
</FormRow> <FormFullWidthLayout>
<FormRow>
<Field name="labels"> <Field name="labels">
{({ field }) => ( {({ field }) => (
<FormGroup label={i18n._(t`Labels`)} fieldId="template-labels"> <FormGroup label={i18n._(t`Labels`)} fieldId="template-labels">
@@ -352,8 +344,6 @@ class JobTemplateForm extends Component {
</FormGroup> </FormGroup>
)} )}
</Field> </Field>
</FormRow>
<FormRow>
<Field name="credentials" fieldId="template-credentials"> <Field name="credentials" fieldId="template-credentials">
{({ field }) => ( {({ field }) => (
<MultiCredentialsLookup <MultiCredentialsLookup
@@ -368,9 +358,8 @@ class JobTemplateForm extends Component {
/> />
)} )}
</Field> </Field>
</FormRow>
<AdvancedFieldsWrapper label="Advanced"> <AdvancedFieldsWrapper label="Advanced">
<FormRow> <FormColumnLayout>
<FormField <FormField
id="template-forks" id="template-forks"
name="forks" name="forks"
@@ -462,13 +451,14 @@ class JobTemplateForm extends Component {
</FormGroup> </FormGroup>
)} )}
</Field> </Field>
</FormRow> <FormFullWidthLayout>
<Field name="instanceGroups"> <Field name="instanceGroups">
{({ field, form }) => ( {({ field, form }) => (
<InstanceGroupsLookup <InstanceGroupsLookup
css="margin-top: 20px"
value={field.value} value={field.value}
onChange={value => form.setFieldValue(field.name, value)} onChange={value =>
form.setFieldValue(field.name, value)
}
tooltip={i18n._(t`Select the Instance Groups for this Organization tooltip={i18n._(t`Select the Instance Groups for this Organization
to run on.`)} to run on.`)}
/> />
@@ -478,7 +468,6 @@ class JobTemplateForm extends Component {
{({ field, form }) => ( {({ field, form }) => (
<FormGroup <FormGroup
label={i18n._(t`Job Tags`)} label={i18n._(t`Job Tags`)}
css="margin-top: 20px"
fieldId="template-job-tags" fieldId="template-job-tags"
> >
<FieldTooltip <FieldTooltip
@@ -490,7 +479,9 @@ class JobTemplateForm extends Component {
/> />
<TagMultiSelect <TagMultiSelect
value={field.value} value={field.value}
onChange={value => form.setFieldValue(field.name, value)} onChange={value =>
form.setFieldValue(field.name, value)
}
/> />
</FormGroup> </FormGroup>
)} )}
@@ -499,7 +490,6 @@ class JobTemplateForm extends Component {
{({ field, form }) => ( {({ field, form }) => (
<FormGroup <FormGroup
label={i18n._(t`Skip Tags`)} label={i18n._(t`Skip Tags`)}
css="margin-top: 20px"
fieldId="template-skip-tags" fieldId="template-skip-tags"
> >
<FieldTooltip <FieldTooltip
@@ -511,17 +501,19 @@ class JobTemplateForm extends Component {
/> />
<TagMultiSelect <TagMultiSelect
value={field.value} value={field.value}
onChange={value => form.setFieldValue(field.name, value)} onChange={value =>
form.setFieldValue(field.name, value)
}
/> />
</FormGroup> </FormGroup>
)} )}
</Field> </Field>
<GridFormGroup <FormGroup
fieldId="template-option-checkboxes" fieldId="template-option-checkboxes"
isInline isInline
label={i18n._(t`Options`)} label={i18n._(t`Options`)}
css="margin-top: 20px"
> >
<FormCheckboxLayout>
<CheckboxField <CheckboxField
id="option-privilege-escalation" id="option-privilege-escalation"
name="become_enabled" name="become_enabled"
@@ -563,14 +555,11 @@ class JobTemplateForm extends Component {
tooltip={i18n._(t`If enabled, use cached facts if available tooltip={i18n._(t`If enabled, use cached facts if available
and store discovered facts in the cache.`)} and store discovered facts in the cache.`)}
/> />
</GridFormGroup> </FormCheckboxLayout>
<div </FormGroup>
css={` </FormFullWidthLayout>
${allowCallbacks ? '' : 'display: none'} {allowCallbacks && (
margin-top: 20px; <>
`}
>
<FormRow>
{callbackUrl && ( {callbackUrl && (
<FormGroup <FormGroup
label={i18n._(t`Provisioning Callback URL`)} label={i18n._(t`Provisioning Callback URL`)}
@@ -589,11 +578,14 @@ class JobTemplateForm extends Component {
label={i18n._(t`Host Config Key`)} label={i18n._(t`Host Config Key`)}
validate={allowCallbacks ? required(null, i18n) : null} validate={allowCallbacks ? required(null, i18n) : null}
/> />
</FormRow> </>
</div> )}
</FormColumnLayout>
</AdvancedFieldsWrapper> </AdvancedFieldsWrapper>
</FormFullWidthLayout>
<FormSubmitError error={submitError} /> <FormSubmitError error={submitError} />
<FormActionGroup onCancel={handleCancel} onSubmit={handleSubmit} /> <FormActionGroup onCancel={handleCancel} onSubmit={handleSubmit} />
</FormColumnLayout>
</Form> </Form>
); );
} }

View File

@@ -10,9 +10,9 @@ import FormField, {
PasswordField, PasswordField,
FormSubmitError, FormSubmitError,
} from '@components/FormField'; } from '@components/FormField';
import FormRow from '@components/FormRow';
import OrganizationLookup from '@components/Lookup/OrganizationLookup'; import OrganizationLookup from '@components/Lookup/OrganizationLookup';
import { required, requiredEmail } from '@util/validators'; import { required, requiredEmail } from '@util/validators';
import { FormColumnLayout } from '@components/FormLayout';
function UserFormFields({ user, i18n }) { function UserFormFields({ user, i18n }) {
const [organization, setOrganization] = useState(null); const [organization, setOrganization] = useState(null);
@@ -99,6 +99,7 @@ function UserFormFields({ user, i18n }) {
type="text" type="text"
/> />
{!user.id && ( {!user.id && (
<<<<<<< HEAD
<OrganizationLookup <OrganizationLookup
helperTextInvalid={organizationMeta.error} helperTextInvalid={organizationMeta.error}
isValid={!organizationMeta.touched || !organizationMeta.error} isValid={!organizationMeta.touched || !organizationMeta.error}
@@ -125,6 +126,34 @@ function UserFormFields({ user, i18n }) {
{...userTypeField} {...userTypeField}
/> />
</FormGroup> </FormGroup>
=======
<OrganizationLookup
helperTextInvalid={organizationMeta.error}
isValid={!organizationMeta.touched || !organizationMeta.error}
onBlur={() => organizationHelpers.setTouched()}
onChange={value => {
organizationHelpers.setValue(value.id);
setOrganization(value);
}}
value={organization}
required
/>
)}
<FormGroup
fieldId="user-type"
helperTextInvalid={userTypeMeta.error}
isRequired
isValid={!userTypeMeta.touched || !userTypeMeta.error}
label={i18n._(t`User Type`)}
>
<AnsibleSelect
isValid={!userTypeMeta.touched || !userTypeMeta.error}
id="user-type"
data={userTypeOptions}
{...userTypeField}
/>
</FormGroup>
>>>>>>> update forms from FormRow to using FormLayout components
</> </>
); );
} }
@@ -173,12 +202,14 @@ function UserForm({ user, handleCancel, handleSubmit, submitError, i18n }) {
> >
{formik => ( {formik => (
<Form autoComplete="off" onSubmit={formik.handleSubmit}> <Form autoComplete="off" onSubmit={formik.handleSubmit}>
<FormColumnLayout>
<UserFormFields user={user} i18n={i18n} /> <UserFormFields user={user} i18n={i18n} />
<FormSubmitError error={submitError} /> <FormSubmitError error={submitError} />
<FormActionGroup <FormActionGroup
onCancel={handleCancel} onCancel={handleCancel}
onSubmit={formik.handleSubmit} onSubmit={formik.handleSubmit}
/> />
</FormColumnLayout>
</Form> </Form>
)} )}
</Formik> </Formik>