Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Edit Dialog #158

Merged
merged 7 commits into from
Mar 23, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 68 additions & 0 deletions app/src/components/dialog/EditDialog.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { render } from '@testing-library/react';
import React from 'react';
import EditDialog from 'components/dialog/EditDialog';
import { useFormikContext } from 'formik';
import { TextField } from '@material-ui/core';
import yup from 'utils/YupSchema';

export interface ISampleFormikForm {
testField: string;
}

export const SampleFormikFormInitialValues: ISampleFormikForm = {
testField: ''
};

export const SampleFormikFormYupSchema = yup.object().shape({
testField: yup
.string()
.max(3000, 'Cannot exceed 3000 characters')
.required('You must provide a test field for the project')
});

const SampleFormikForm = () => {
const formikProps = useFormikContext<ISampleFormikForm>();

const { values, handleChange, handleSubmit } = formikProps;

return (
<form onSubmit={handleSubmit}>
<TextField
id="testField"
name="testField"
label="Test Field"
multiline
required={true}
rows={4}
fullWidth
variant="outlined"
value={values.testField}
onChange={handleChange}
/>
</form>
);
};

describe('EditDialog', () => {
it('matches the snapshot with no error message', () => {
const { baseElement } = render(
<div id="root">
<EditDialog
dialogTitle="This is dialog title"
dialogText="This is dialog text"
open={true}
component={{
element: <SampleFormikForm />,
initialValues: SampleFormikFormInitialValues,
validationSchema: SampleFormikFormYupSchema
}}
onClose={() => jest.fn()}
onCancel={() => jest.fn()}
onSave={() => jest.fn()}
/>
</div>
);

expect(baseElement).toMatchSnapshot();
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we need to add a test case for when the Yes button is clicked and the onSave is called I think
possibly also for oncancel

});
104 changes: 104 additions & 0 deletions app/src/components/dialog/EditDialog.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import { Box, Button, Dialog, DialogActions, DialogContent, DialogContentText, DialogTitle } from '@material-ui/core';
import React from 'react';
import { Formik } from 'formik';

export interface IEditDialogComponentProps {
element: any;
initialValues: any;
validationSchema: any;
}

export interface IEditDialogProps {
/**
* The dialog window title text.
*
* @type {string}
* @memberof IEditDialogProps
*/
dialogTitle: string;
/**
* The dialog window body text.
*
* @type {string}
* @memberof IEditDialogProps
*/
dialogText: string;
/**
* Set to `true` to open the dialog, `false` to close the dialog.
*
* @type {boolean}
* @memberof IEditDialogProps
*/
open: boolean;

/**
* @type {IEditDialogComponentProps}
* @memberof IEditDialogProps
*/
component: IEditDialogComponentProps;

/**
* Callback fired if the dialog is closed.
*
* @memberof IEditDialogProps
*/
onClose: () => void;
/**
* Callback fired if the 'No' button is clicked.
*
* @memberof IEditDialogProps
*/
onCancel: () => void;
/**
* Callback fired if the 'Yes' button is clicked.
*
* @memberof IEditDialogProps
*/
onSave: (values: any) => void;
}

/**
* A dialog for displaying a component for editing purposes and giving the user the option to say
* `Yes`(Save) or `No`.
*
* @param {*} props
* @return {*}
*/
export const EditDialog: React.FC<IEditDialogProps> = (props) => {
return (
<Box>
<Formik
initialValues={props.component.initialValues}
validationSchema={props.component.validationSchema}
validateOnBlur={true}
validateOnChange={false}
onSubmit={(values) => {
props.onSave(values);
}}>
{(formikProps) => (
<Dialog
open={props.open}
onClose={props.onClose}
aria-labelledby="edit-dialog-title"
aria-describedby="edit-dialog-description">
<DialogTitle id="edit-dialog-title">{props.dialogTitle}</DialogTitle>
<DialogContent>
{props?.component?.element}
<DialogContentText id="edit-dialog-description">{props.dialogText}</DialogContentText>
</DialogContent>
<DialogActions>
<Button onClick={props.onCancel} color="primary">
No
</Button>
<Button onClick={formikProps.submitForm} color="primary" autoFocus>
Yes
</Button>
</DialogActions>
</Dialog>
)}
</Formik>
</Box>
);
};

export default EditDialog;
159 changes: 159 additions & 0 deletions app/src/components/dialog/__snapshots__/EditDialog.test.tsx.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`EditDialog matches the snapshot with no error message 1`] = `
<body
style="padding-right: 0px; overflow: hidden;"
>
<div
aria-hidden="true"
>
<div
id="root"
>
<div
class="MuiBox-root MuiBox-root-1"
/>
</div>
</div>
<div
class="MuiDialog-root"
role="presentation"
style="position: fixed; z-index: 1300; right: 0px; bottom: 0px; top: 0px; left: 0px;"
>
<div
aria-hidden="true"
class="MuiBackdrop-root"
style="opacity: 1; webkit-transition: opacity 225ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; transition: opacity 225ms cubic-bezier(0.4, 0, 0.2, 1) 0ms;"
/>
<div
data-test="sentinelStart"
tabindex="0"
/>
<div
class="MuiDialog-container MuiDialog-scrollPaper"
role="none presentation"
style="opacity: 1; webkit-transition: opacity 225ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; transition: opacity 225ms cubic-bezier(0.4, 0, 0.2, 1) 0ms;"
tabindex="-1"
>
<div
aria-describedby="edit-dialog-description"
aria-labelledby="edit-dialog-title"
class="MuiPaper-root MuiDialog-paper MuiDialog-paperScrollPaper MuiDialog-paperWidthSm MuiPaper-elevation24 MuiPaper-rounded"
role="dialog"
>
<div
class="MuiDialogTitle-root"
id="edit-dialog-title"
>
<h2
class="MuiTypography-root MuiTypography-h6"
>
This is dialog title
</h2>
</div>
<div
class="MuiDialogContent-root"
>
<form>
<div
class="MuiFormControl-root MuiTextField-root MuiFormControl-fullWidth"
>
<label
class="MuiFormLabel-root MuiInputLabel-root MuiInputLabel-formControl MuiInputLabel-animated MuiInputLabel-outlined Mui-required Mui-required"
data-shrink="false"
for="testField"
id="testField-label"
>
Test Field
<span
aria-hidden="true"
class="MuiFormLabel-asterisk MuiInputLabel-asterisk"
>

*
</span>
</label>
<div
class="MuiInputBase-root MuiOutlinedInput-root MuiInputBase-fullWidth MuiInputBase-formControl MuiInputBase-multiline MuiOutlinedInput-multiline"
>
<textarea
aria-invalid="false"
class="MuiInputBase-input MuiOutlinedInput-input MuiInputBase-inputMultiline MuiOutlinedInput-inputMultiline"
id="testField"
name="testField"
required=""
rows="4"
/>
<fieldset
aria-hidden="true"
class="PrivateNotchedOutline-root-2 MuiOutlinedInput-notchedOutline"
>
<legend
class="PrivateNotchedOutline-legendLabelled-4"
>
<span>
Test Field
 *
</span>
</legend>
</fieldset>
</div>
</div>
</form>
<p
class="MuiTypography-root MuiDialogContentText-root MuiTypography-body1 MuiTypography-colorTextSecondary"
id="edit-dialog-description"
>
This is dialog text
</p>
</div>
<div
class="MuiDialogActions-root MuiDialogActions-spacing"
>
<button
class="MuiButtonBase-root MuiButton-root MuiButton-text MuiButton-textPrimary"
tabindex="0"
type="button"
>
<span
class="MuiButton-label"
>
No
</span>
<span
class="MuiTouchRipple-root"
/>
</button>
<button
class="MuiButtonBase-root MuiButton-root MuiButton-text MuiButton-textPrimary Mui-focusVisible Mui-focusVisible"
tabindex="0"
type="button"
>
<span
class="MuiButton-label"
>
Yes
</span>
<span
class="MuiTouchRipple-root"
>
<span
class="MuiTouchRipple-ripple MuiTouchRipple-rippleVisible MuiTouchRipple-ripplePulsate"
style="width: 1px; height: 1px; top: -0.5px; left: -0.5px;"
>
<span
class="MuiTouchRipple-child MuiTouchRipple-childPulsate"
/>
</span>
</span>
</button>
</div>
</div>
</div>
<div
data-test="sentinelEnd"
tabindex="0"
/>
</div>
</body>
`;
8 changes: 8 additions & 0 deletions app/src/constants/i18n.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,11 @@ export const UploadProjectArtifactsI18N = {
uploadErrorText:
'An error has occurred while attempting to upload project artifacts, please try again. If the error persists, please contact your system administrator.'
};

export const EditObjectivesI18N = {
editTitle: 'Edit Project Objectives',
editText: 'Are you sure you want to save?',
createErrorTitle: 'Error Editing Project Objectives',
createErrorText:
'An error has occurred while attempting to edit your project objectives, please try again. If the error persists, please contact your system administrator.'
};
14 changes: 11 additions & 3 deletions app/src/features/projects/view/ProjectDetails.test.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import { render } from '@testing-library/react';
import { codes } from 'test-helpers/code-helpers';
import { createMemoryHistory } from 'history';
import React from 'react';
import ProjectDetails from './ProjectDetails';
import { Router } from 'react-router';
import { codes } from 'test-helpers/code-helpers';
import { getProjectForViewResponse } from 'test-helpers/project-helpers';
import ProjectDetails from './ProjectDetails';

const history = createMemoryHistory();

describe('ProjectDetails', () => {
it('renders correctly', () => {
Expand All @@ -18,7 +22,11 @@ describe('ProjectDetails', () => {
}
});

const { asFragment } = render(<ProjectDetails projectForViewData={getProjectForViewResponse} codes={codes} />);
const { asFragment } = render(
<Router history={history}>
<ProjectDetails projectForViewData={getProjectForViewResponse} codes={codes} />
</Router>
);

expect(asFragment()).toMatchSnapshot();
});
Expand Down
Loading