add FormSubmitError component

This commit is contained in:
Keith Grant
2020-02-04 09:58:22 -08:00
parent cab25656eb
commit a934e146ee
5 changed files with 60 additions and 45 deletions

View File

@@ -0,0 +1,42 @@
import React, { useState, useEffect } from 'react';
import { useFormikContext } from 'formik';
import { t } from '@lingui/macro';
import { withI18n } from '@lingui/react';
import ErrorDetail from '@components/ErrorDetail';
import AlertModal from '@components/AlertModal';
function FormSubmitError({ error, i18n }) {
const [formError, setFormError] = useState(null);
const { setErrors } = useFormikContext();
useEffect(() => {
if (!error) {
return;
}
// check for field-specific errors from API
if (error.response?.data && typeof error.response.data === 'object') {
setErrors(error.response.data);
setFormError(null);
} else {
setFormError(error);
}
}, [error, setErrors]);
if (!formError) {
return null;
}
return (
<AlertModal
variant="danger"
title={i18n._(t`Error!`)}
isOpen={formError}
onClose={() => setFormError(null)}
>
{i18n._(t`An error occurred when saving`)}
<ErrorDetail error={formError} />
</AlertModal>
);
}
export default withI18n()(FormSubmitError);

View File

@@ -2,3 +2,4 @@ export { default } from './FormField';
export { default as CheckboxField } from './CheckboxField'; export { default as CheckboxField } from './CheckboxField';
export { default as FieldTooltip } from './FieldTooltip'; export { default as FieldTooltip } from './FieldTooltip';
export { default as PasswordField } from './PasswordField'; export { default as PasswordField } from './PasswordField';
export { default as FormSubmitError } from './FormSubmitError';

View File

@@ -1,15 +1,11 @@
import React, { useState } from 'react'; import React, { useState } from 'react';
import { useHistory } from 'react-router-dom'; import { useHistory } from 'react-router-dom';
import { t } from '@lingui/macro';
import { withI18n } from '@lingui/react';
import { Card } from '@patternfly/react-core'; import { Card } from '@patternfly/react-core';
import { CardBody } from '@components/Card'; import { CardBody } from '@components/Card';
import ErrorDetail from '@components/ErrorDetail';
import AlertModal from '@components/AlertModal';
import JobTemplateForm from '../shared/JobTemplateForm'; import JobTemplateForm from '../shared/JobTemplateForm';
import { JobTemplatesAPI } from '@api'; import { JobTemplatesAPI } from '@api';
function JobTemplateAdd({ i18n }) { function JobTemplateAdd() {
const [formSubmitError, setFormSubmitError] = useState(null); const [formSubmitError, setFormSubmitError] = useState(null);
const history = useHistory(); const history = useHistory();
@@ -35,10 +31,6 @@ function JobTemplateAdd({ i18n }) {
]); ]);
history.push(`/templates/${type}/${id}/details`); history.push(`/templates/${type}/${id}/details`);
} catch (error) { } catch (error) {
// check for field-specific errors from API
if (error.response?.data && typeof error.response.data === 'object') {
throw error.response.data;
}
setFormSubmitError(error); setFormSubmitError(error);
} }
} }
@@ -74,21 +66,11 @@ function JobTemplateAdd({ i18n }) {
<JobTemplateForm <JobTemplateForm
handleCancel={handleCancel} handleCancel={handleCancel}
handleSubmit={handleSubmit} handleSubmit={handleSubmit}
submitError={formSubmitError}
/> />
</CardBody> </CardBody>
{formSubmitError && (
<AlertModal
variant="danger"
title={i18n._(t`Error!`)}
isOpen={formSubmitError}
onClose={() => setFormSubmitError(null)}
>
{i18n._(t`An error occurred when saving`)}
<ErrorDetail error={formSubmitError} />
</AlertModal>
)}
</Card> </Card>
); );
} }
export default withI18n()(JobTemplateAdd); export default JobTemplateAdd;

View File

@@ -1,13 +1,9 @@
/* eslint react/no-unused-state: 0 */ /* eslint react/no-unused-state: 0 */
import React, { Component } from 'react'; import React, { Component } from 'react';
import { withRouter, Redirect } from 'react-router-dom'; import { withRouter, Redirect } from 'react-router-dom';
import { t } from '@lingui/macro';
import { withI18n } from '@lingui/react';
import { CardBody } from '@components/Card'; import { CardBody } from '@components/Card';
import ContentError from '@components/ContentError'; import ContentError from '@components/ContentError';
import ContentLoading from '@components/ContentLoading'; import ContentLoading from '@components/ContentLoading';
import ErrorDetail from '@components/ErrorDetail';
import AlertModal from '@components/AlertModal';
import { JobTemplatesAPI, ProjectsAPI } from '@api'; import { JobTemplatesAPI, ProjectsAPI } from '@api';
import { JobTemplate } from '@types'; import { JobTemplate } from '@types';
import { getAddedAndRemoved } from '@util/lists'; import { getAddedAndRemoved } from '@util/lists';
@@ -118,10 +114,6 @@ class JobTemplateEdit extends Component {
]); ]);
history.push(this.detailsUrl); history.push(this.detailsUrl);
} catch (error) { } catch (error) {
// check for field-specific errors from API
if (error.response?.data && typeof error.response.data === 'object') {
throw error.response.data;
}
this.setState({ formSubmitError: error }); this.setState({ formSubmitError: error });
} }
} }
@@ -181,7 +173,7 @@ class JobTemplateEdit extends Component {
} }
render() { render() {
const { template, i18n } = this.props; const { template } = this.props;
const { const {
contentError, contentError,
formSubmitError, formSubmitError,
@@ -217,21 +209,11 @@ class JobTemplateEdit extends Component {
handleCancel={this.handleCancel} handleCancel={this.handleCancel}
handleSubmit={this.handleSubmit} handleSubmit={this.handleSubmit}
relatedProjectPlaybooks={relatedProjectPlaybooks} relatedProjectPlaybooks={relatedProjectPlaybooks}
submitError={formSubmitError}
/> />
{formSubmitError && (
<AlertModal
variant="danger"
title={i18n._(t`Error!`)}
isOpen={formSubmitError}
onClose={() => this.setState({ formSubmitError: null })}
>
{i18n._(t`An error occurred when saving`)}
<ErrorDetail error={formSubmitError} />
</AlertModal>
)}
</CardBody> </CardBody>
); );
} }
} }
export default withI18n()(withRouter(JobTemplateEdit)); export default withRouter(JobTemplateEdit);

View File

@@ -16,7 +16,11 @@ import ContentLoading from '@components/ContentLoading';
import AnsibleSelect from '@components/AnsibleSelect'; import AnsibleSelect from '@components/AnsibleSelect';
import { TagMultiSelect } from '@components/MultiSelect'; import { TagMultiSelect } from '@components/MultiSelect';
import FormActionGroup from '@components/FormActionGroup'; import FormActionGroup from '@components/FormActionGroup';
import FormField, { CheckboxField, FieldTooltip } from '@components/FormField'; import FormField, {
CheckboxField,
FieldTooltip,
FormSubmitError,
} from '@components/FormField';
import FormRow from '@components/FormRow'; import FormRow from '@components/FormRow';
import CollapsibleSection from '@components/CollapsibleSection'; import CollapsibleSection from '@components/CollapsibleSection';
import { required } from '@util/validators'; import { required } from '@util/validators';
@@ -48,6 +52,7 @@ class JobTemplateForm extends Component {
template: JobTemplate, template: JobTemplate,
handleCancel: PropTypes.func.isRequired, handleCancel: PropTypes.func.isRequired,
handleSubmit: PropTypes.func.isRequired, handleSubmit: PropTypes.func.isRequired,
submitError: PropTypes.shape({}),
}; };
static defaultProps = { static defaultProps = {
@@ -66,6 +71,7 @@ class JobTemplateForm extends Component {
}, },
isNew: true, isNew: true,
}, },
submitError: null,
}; };
constructor(props) { constructor(props) {
@@ -161,9 +167,9 @@ class JobTemplateForm extends Component {
handleSubmit, handleSubmit,
handleBlur, handleBlur,
setFieldValue, setFieldValue,
i18n,
template, template,
formik, submitError,
i18n,
} = this.props; } = this.props;
const jobTypeOptions = [ const jobTypeOptions = [
@@ -202,6 +208,7 @@ class JobTemplateForm extends Component {
if (contentError) { if (contentError) {
return <ContentError error={contentError} />; return <ContentError error={contentError} />;
} }
const AdvancedFieldsWrapper = template.isNew ? CollapsibleSection : 'div'; const AdvancedFieldsWrapper = template.isNew ? CollapsibleSection : 'div';
return ( return (
<Form autoComplete="off" onSubmit={handleSubmit}> <Form autoComplete="off" onSubmit={handleSubmit}>
@@ -587,6 +594,7 @@ class JobTemplateForm extends Component {
</div> </div>
</AdvancedFieldsWrapper> </AdvancedFieldsWrapper>
<FormActionGroup onCancel={handleCancel} onSubmit={handleSubmit} /> <FormActionGroup onCancel={handleCancel} onSubmit={handleSubmit} />
<FormSubmitError error={submitError} />
</Form> </Form>
); );
} }