mirror of
https://github.com/ansible/awx.git
synced 2026-02-04 19:18:13 -03:30
add FormSubmitError component
This commit is contained in:
42
awx/ui_next/src/components/FormField/FormSubmitError.jsx
Normal file
42
awx/ui_next/src/components/FormField/FormSubmitError.jsx
Normal 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);
|
||||||
@@ -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';
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user