diff --git a/awx/ui_next/src/screens/Template/JobTemplateAdd/JobTemplateAdd.jsx b/awx/ui_next/src/screens/Template/JobTemplateAdd/JobTemplateAdd.jsx
index 7aecba1eb2..a4511f4e10 100644
--- a/awx/ui_next/src/screens/Template/JobTemplateAdd/JobTemplateAdd.jsx
+++ b/awx/ui_next/src/screens/Template/JobTemplateAdd/JobTemplateAdd.jsx
@@ -1,11 +1,15 @@
import React, { useState } from 'react';
import { useHistory } from 'react-router-dom';
+import { t } from '@lingui/macro';
+import { withI18n } from '@lingui/react';
import { Card } from '@patternfly/react-core';
import { CardBody } from '@components/Card';
+import ErrorDetail from '@components/ErrorDetail';
+import AlertModal from '@components/AlertModal';
import JobTemplateForm from '../shared/JobTemplateForm';
import { JobTemplatesAPI } from '@api';
-function JobTemplateAdd() {
+function JobTemplateAdd({ i18n }) {
const [formSubmitError, setFormSubmitError] = useState(null);
const history = useHistory();
@@ -31,6 +35,10 @@ function JobTemplateAdd() {
]);
history.push(`/templates/${type}/${id}/details`);
} catch (error) {
+ // check for field-specific errors from API
+ if (error.response?.data && typeof error.response.data === 'object') {
+ throw error.response.data;
+ }
setFormSubmitError(error);
}
}
@@ -68,9 +76,19 @@ function JobTemplateAdd() {
handleSubmit={handleSubmit}
/>
- {formSubmitError ?
formSubmitError
: ''}
+ {formSubmitError && (
+ setFormSubmitError(null)}
+ >
+ {i18n._(t`An error occurred when saving`)}
+
+
+ )}
);
}
-export default JobTemplateAdd;
+export default withI18n()(JobTemplateAdd);
diff --git a/awx/ui_next/src/screens/Template/JobTemplateEdit/JobTemplateEdit.jsx b/awx/ui_next/src/screens/Template/JobTemplateEdit/JobTemplateEdit.jsx
index 73d90a8a26..07e1085936 100644
--- a/awx/ui_next/src/screens/Template/JobTemplateEdit/JobTemplateEdit.jsx
+++ b/awx/ui_next/src/screens/Template/JobTemplateEdit/JobTemplateEdit.jsx
@@ -1,9 +1,13 @@
/* eslint react/no-unused-state: 0 */
import React, { Component } from 'react';
import { withRouter, Redirect } from 'react-router-dom';
+import { t } from '@lingui/macro';
+import { withI18n } from '@lingui/react';
import { CardBody } from '@components/Card';
import ContentError from '@components/ContentError';
import ContentLoading from '@components/ContentLoading';
+import ErrorDetail from '@components/ErrorDetail';
+import AlertModal from '@components/AlertModal';
import { JobTemplatesAPI, ProjectsAPI } from '@api';
import { JobTemplate } from '@types';
import { getAddedAndRemoved } from '@util/lists';
@@ -113,8 +117,12 @@ class JobTemplateEdit extends Component {
this.submitCredentials(credentials),
]);
history.push(this.detailsUrl);
- } catch (formSubmitError) {
- this.setState({ formSubmitError });
+ } 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 });
}
}
@@ -173,7 +181,7 @@ class JobTemplateEdit extends Component {
}
render() {
- const { template } = this.props;
+ const { template, i18n } = this.props;
const {
contentError,
formSubmitError,
@@ -210,10 +218,20 @@ class JobTemplateEdit extends Component {
handleSubmit={this.handleSubmit}
relatedProjectPlaybooks={relatedProjectPlaybooks}
/>
- {formSubmitError ? error
: null}
+ {formSubmitError && (
+ this.setState({ formSubmitError: null })}
+ >
+ {i18n._(t`An error occurred when saving`)}
+
+
+ )}
);
}
}
-export default withRouter(JobTemplateEdit);
+export default withI18n()(withRouter(JobTemplateEdit));
diff --git a/awx/ui_next/src/screens/Template/shared/JobTemplateForm.jsx b/awx/ui_next/src/screens/Template/shared/JobTemplateForm.jsx
index c2f1ca9c4c..19973cfdd5 100644
--- a/awx/ui_next/src/screens/Template/shared/JobTemplateForm.jsx
+++ b/awx/ui_next/src/screens/Template/shared/JobTemplateForm.jsx
@@ -163,6 +163,7 @@ class JobTemplateForm extends Component {
setFieldValue,
i18n,
template,
+ formik,
} = this.props;
const jobTypeOptions = [
@@ -631,7 +632,13 @@ const FormikApp = withFormik({
credentials: summary_fields.credentials || [],
};
},
- handleSubmit: (values, { props }) => props.handleSubmit(values),
+ handleSubmit: async (values, { props, setErrors }) => {
+ try {
+ await props.handleSubmit(values);
+ } catch (errors) {
+ setErrors(errors);
+ }
+ },
})(JobTemplateForm);
export { JobTemplateForm as _JobTemplateForm };