Skip to content

Commit 6a3895d

Browse files
committed
#3667: with @Jfresh18 -- added form validation to TaskFormModal and fixed form clearing issue on incomplete submit
1 parent eb74e08 commit 6a3895d

3 files changed

Lines changed: 54 additions & 34 deletions

File tree

src/frontend/src/components/NERFormModal.tsx

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { ReactNode } from 'react';
22
import { FieldValues, UseFormHandleSubmit, UseFormReset } from 'react-hook-form';
33
import NERModal, { NERModalProps } from './NERModal';
4+
import { useToast } from '../hooks/toasts.hooks';
45

56
interface NERFormModalProps<T extends FieldValues> extends NERModalProps {
67
reset: UseFormReset<T>;
@@ -27,18 +28,23 @@ const NERFormModal = ({
2728
hideBackDrop = false,
2829
paperProps
2930
}: NERFormModalProps<any>) => {
31+
const toast = useToast();
3032
/**
3133
* Wrapper function for onSubmit so that form data is reset after submit
3234
*/
3335
const onSubmitWrapper = async (data: any) => {
34-
await onFormSubmit(data);
35-
reset();
36+
try {
37+
await onFormSubmit(data);
38+
reset();
39+
} catch (e: unknown) {
40+
if (e instanceof Error) toast.error(e.message, 6000);
41+
}
3642
};
3743

38-
const handleFormSubmit = (e: React.FormEvent<HTMLFormElement>) => {
44+
const handleFormSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
3945
e.preventDefault();
4046
e.stopPropagation(); // Prevent event bubbling
41-
handleUseFormSubmit(onSubmitWrapper)(e);
47+
await handleUseFormSubmit(onSubmitWrapper)(e);
4248
};
4349

4450
return (

src/frontend/src/pages/ProjectDetailPage/ProjectViewContainer/TaskList/TaskFormModal.tsx

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,14 @@ import { yupResolver } from '@hookform/resolvers/yup';
22
import { Autocomplete, FormControl, FormHelperText, FormLabel, Grid, MenuItem, TextField } from '@mui/material';
33
import { DatePicker } from '@mui/x-date-pickers';
44
import { Controller, useForm } from 'react-hook-form';
5-
import { countWords, isGuest, isUnderWordCount, notGuest, Task, TaskPriority, TeamPreview } from 'shared';
5+
import { countWords, isGuest, isUnderWordCount, notGuest, Task, TaskStatus, TaskPriority, TeamPreview } from 'shared';
66
import { useAllUsers, useCurrentUser } from '../../../../hooks/users.hooks';
77
import * as yup from 'yup';
88
import { taskUserToAutocompleteOption } from '../../../../utils/task.utils';
99
import NERFormModal from '../../../../components/NERFormModal';
1010
import LoadingIndicator from '../../../../components/LoadingIndicator';
1111
import ErrorPage from '../../../ErrorPage';
1212

13-
const schema = yup.object().shape({
14-
notes: yup.string().optional(),
15-
startDate: yup.date().optional(),
16-
deadline: yup.date().optional(),
17-
priority: yup.mixed<TaskPriority>().oneOf(Object.values(TaskPriority)).required(),
18-
assignees: yup.array().required(),
19-
title: yup.string().required(),
20-
taskId: yup.string().required()
21-
});
22-
2313
export interface EditTaskFormInput {
2414
taskId: string;
2515
title: string;
@@ -32,14 +22,41 @@ export interface EditTaskFormInput {
3222

3323
interface TaskFormModalProps {
3424
task?: Task;
25+
status?: Task['status'];
3526
teams: TeamPreview[];
3627
modalShow: boolean;
3728
onHide: () => void;
3829
onSubmit: (data: EditTaskFormInput) => Promise<void>;
3930
onReset?: () => void;
4031
}
4132

42-
const TaskFormModal: React.FC<TaskFormModalProps> = ({ task, onSubmit, modalShow, onHide, onReset }) => {
33+
const TaskFormModal: React.FC<TaskFormModalProps> = ({ task, status, onSubmit, modalShow, onHide, onReset }) => {
34+
let schema;
35+
36+
if (status === TaskStatus.IN_PROGRESS) {
37+
console.log('here');
38+
schema = yup.object().shape({
39+
notes: yup.string().optional(),
40+
startDate: yup.date().optional(),
41+
deadline: yup.date().required('Deadline is required for In Progress tasks'),
42+
priority: yup.mixed<TaskPriority>().oneOf(Object.values(TaskPriority)).required(),
43+
assignees: yup.array().required().min(1, 'At least one assignee is required for In Progress tasks'),
44+
title: yup.string().required(),
45+
taskId: yup.string().required()
46+
});
47+
} else {
48+
console.log('there');
49+
schema = yup.object().shape({
50+
notes: yup.string().optional(),
51+
startDate: yup.date().optional(),
52+
deadline: yup.date().optional(),
53+
priority: yup.mixed<TaskPriority>().oneOf(Object.values(TaskPriority)).required(),
54+
assignees: yup.array().required(),
55+
title: yup.string().required(),
56+
taskId: yup.string().required()
57+
});
58+
}
59+
4360
const user = useCurrentUser();
4461

4562
const { data: users, isLoading, isError, error } = useAllUsers();
@@ -161,6 +178,7 @@ const TaskFormModal: React.FC<TaskFormModalProps> = ({ task, onSubmit, modalShow
161178
/>
162179
)}
163180
/>
181+
<FormHelperText error={!!errors.assignees}>{errors.assignees?.message}</FormHelperText>
164182
</FormControl>
165183
</Grid>
166184
<Grid item md={6}>
@@ -199,6 +217,7 @@ const TaskFormModal: React.FC<TaskFormModalProps> = ({ task, onSubmit, modalShow
199217
/>
200218
)}
201219
/>
220+
<FormHelperText error={!!errors.deadline}>{errors.deadline?.message}</FormHelperText>
202221
</FormControl>
203222
</Grid>
204223
<Grid item xs={12} md={12}>

src/frontend/src/pages/ProjectDetailPage/ProjectViewContainer/TaskList/v2/TaskColumn.tsx

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -30,30 +30,25 @@ export const TaskColumn = ({
3030
const theme = useTheme();
3131

3232
const handleCreateTask = async ({ notes, title, deadline, assignees, priority, startDate }: EditTaskFormInput) => {
33-
try {
34-
const task = await createTask({
35-
wbsNum: project.wbsNum,
36-
title,
37-
deadline: deadline ? transformDate(deadline) : undefined,
38-
startDate: startDate ? transformDate(startDate) : undefined,
39-
priority,
40-
status: status as TaskStatus,
41-
assignees,
42-
notes
43-
});
44-
onAddTask(task);
45-
toast.success('Task Successfully Created!');
46-
} catch (e: unknown) {
47-
if (e instanceof Error) {
48-
toast.error(e.message, 6000);
49-
}
50-
}
33+
const task = await createTask({
34+
wbsNum: project.wbsNum,
35+
title,
36+
deadline: deadline ? transformDate(deadline) : undefined,
37+
startDate: startDate ? transformDate(startDate) : undefined,
38+
priority,
39+
status: status as TaskStatus,
40+
assignees,
41+
notes
42+
});
43+
onAddTask(task);
44+
toast.success('Task Successfully Created!');
5145
setShowCreateTaskModal(false);
5246
};
5347

5448
return (
5549
<>
5650
<TaskFormModal
51+
status={status}
5752
onSubmit={handleCreateTask}
5853
onHide={() => setShowCreateTaskModal(false)}
5954
modalShow={showCreateTaskModal}

0 commit comments

Comments
 (0)