move FormSubmitError to inline beside form buttons; add tests

This commit is contained in:
Keith Grant 2020-02-05 10:45:32 -08:00
parent a934e146ee
commit b7f3852ef9
4 changed files with 85 additions and 26 deletions

View File

@ -1,9 +1,14 @@
import React from 'react';
import PropTypes from 'prop-types';
import styled from 'styled-components';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import { ActionGroup as PFActionGroup, Button } from '@patternfly/react-core';
import styled from 'styled-components';
const ErrorMessage = styled('div')`
color: var(--pf-global--danger-color--200);
font-weight: var(--pf-global--FontWeight--bold);
`;
const ActionGroup = styled(PFActionGroup)`
display: flex;
@ -11,19 +16,25 @@ const ActionGroup = styled(PFActionGroup)`
--pf-c-form__group--m-action--MarginTop: 0;
.pf-c-form__actions {
display: grid;
gap: 24px;
grid-template-columns: auto auto;
margin: 0;
& > button {
margin: 0;
}
& > :not(:first-child) {
margin-left: 24px;
}
}
`;
const FormActionGroup = ({ onSubmit, submitDisabled, onCancel, i18n }) => (
const FormActionGroup = ({
onSubmit,
submitDisabled,
onCancel,
errorMessage,
i18n,
}) => (
<ActionGroup>
{errorMessage ? <ErrorMessage>{errorMessage}</ErrorMessage> : null}
<Button
aria-label={i18n._(t`Save`)}
variant="primary"
@ -48,10 +59,12 @@ FormActionGroup.propTypes = {
onCancel: PropTypes.func.isRequired,
onSubmit: PropTypes.func.isRequired,
submitDisabled: PropTypes.bool,
errorMessage: PropTypes.node,
};
FormActionGroup.defaultProps = {
submitDisabled: false,
errorMessage: null,
};
export default withI18n()(FormActionGroup);

View File

@ -1,11 +1,7 @@
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 }) {
function FormSubmitError({ error }) {
const [formError, setFormError] = useState(null);
const { setErrors } = useFormikContext();
@ -18,6 +14,8 @@ function FormSubmitError({ error, i18n }) {
setErrors(error.response.data);
setFormError(null);
} else {
/* eslint-disable-next-line no-console */
console.error(error);
setFormError(error);
}
}, [error, setErrors]);
@ -26,17 +24,7 @@ function FormSubmitError({ error, i18n }) {
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>
);
return <span>{formError.message}</span>;
}
export default withI18n()(FormSubmitError);
export default FormSubmitError;

View File

@ -0,0 +1,55 @@
import React from 'react';
import { act } from 'react-dom/test-utils';
import { mountWithContexts } from '@testUtils/enzymeHelpers';
import { Formik } from 'formik';
import FormSubmitError from './FormSubmitError';
describe('<FormSubmitError>', () => {
test('should render null when no error present', () => {
const wrapper = mountWithContexts(
<Formik>{() => <FormSubmitError error={null} />}</Formik>
);
expect(wrapper.find('FormSubmitError').text()).toEqual('');
});
test('should pass field errors to Formik', () => {
const error = {
response: {
data: {
name: 'invalid',
},
},
};
const wrapper = mountWithContexts(
<Formik>
{({ errors }) => (
<div>
<p>{errors.name}</p>
<FormSubmitError error={error} />
</div>
)}
</Formik>
);
expect(wrapper.find('p').text()).toEqual('invalid');
});
test('should display error message if field errors not provided', async () => {
const realConsole = global.console;
global.console = {
error: jest.fn(),
};
const error = {
message: 'There was an error',
};
let wrapper;
await act(async () => {
wrapper = mountWithContexts(
<Formik>{() => <FormSubmitError error={error} />}</Formik>
);
});
wrapper.update();
expect(wrapper.text()).toEqual('There was an error');
expect(global.console.error).toHaveBeenCalledWith(error);
global.console = realConsole;
});
});

View File

@ -593,8 +593,11 @@ class JobTemplateForm extends Component {
</FormRow>
</div>
</AdvancedFieldsWrapper>
<FormActionGroup onCancel={handleCancel} onSubmit={handleSubmit} />
<FormSubmitError error={submitError} />
<FormActionGroup
onCancel={handleCancel}
onSubmit={handleSubmit}
errorMessage={<FormSubmitError error={submitError} />}
/>
</Form>
);
}