Skip to content

Commit f7ecbd1

Browse files
committed
#1182 - clean up code
1 parent 1e103b5 commit f7ecbd1

13 files changed

Lines changed: 80 additions & 75 deletions

File tree

src/backend/src/routes/teams.routes.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import express from 'express';
22
import TeamsController from '../controllers/teams.controllers';
33
import { body } from 'express-validator';
44
import { validateInputs } from '../utils/utils';
5-
import { intMinZero } from '../utils/validation.utils';
5+
import { intMinZero, nonEmptyString } from '../utils/validation.utils';
66

77
const teamsRouter = express.Router();
88

@@ -24,10 +24,10 @@ teamsRouter.post(
2424
teamsRouter.post('/:teamId/set-head', intMinZero(body('userId')), validateInputs, TeamsController.setTeamHead);
2525
teamsRouter.post(
2626
'/create',
27-
body('teamName').isString(),
27+
nonEmptyString(body('teamName')),
2828
intMinZero(body('headId')),
29-
body('slackId').isString(),
30-
body('description').isString(),
29+
nonEmptyString(body('slackId')),
30+
nonEmptyString(body('description')),
3131
TeamsController.createTeam
3232
);
3333

src/backend/src/services/teams.services.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -192,12 +192,12 @@ export default class TeamsService {
192192
if (!newHead) throw new NotFoundException('User', headId);
193193
if (!isHead(newHead.role)) throw new HttpException(400, 'The team head must be at least a head');
194194

195-
// checking to see if any other teams have the new head as their current head or lead
195+
// checking to see if any other teams have the new head as their current head
196196
const newHeadTeam = await prisma.team.findFirst({
197197
where: { headId }
198198
});
199199

200-
if (newHeadTeam) throw new HttpException(400, 'The new team head must not be a head or lead of another team');
200+
if (newHeadTeam) throw new HttpException(400, 'The new team head must not be a head of another team');
201201

202202
const duplicateName = await prisma.team.findFirst({
203203
where: { teamName }

src/frontend/src/components/NERAutocomplete.tsx

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import {
77
Autocomplete,
88
AutocompleteRenderInputParams,
9+
FormHelperText,
910
InputAdornment,
1011
SxProps,
1112
TextField,
@@ -14,6 +15,7 @@ import {
1415
} from '@mui/material';
1516
import SearchIcon from '@mui/icons-material/Search';
1617
import { HTMLAttributes } from 'react';
18+
import { FieldError } from 'react-hook-form';
1719

1820
interface NERAutocompleteProps {
1921
id: string;
@@ -25,6 +27,7 @@ interface NERAutocompleteProps {
2527
value?: { label: string; id: string } | null;
2628
listboxProps?: HTMLAttributes<HTMLUListElement>;
2729
filterSelectedOptions?: boolean;
30+
errorMessage?: FieldError;
2831
}
2932

3033
const NERAutocomplete: React.FC<NERAutocompleteProps> = ({
@@ -36,7 +39,8 @@ const NERAutocomplete: React.FC<NERAutocompleteProps> = ({
3639
sx,
3740
value,
3841
listboxProps,
39-
filterSelectedOptions
42+
filterSelectedOptions,
43+
errorMessage
4044
}) => {
4145
const theme = useTheme();
4246

@@ -75,19 +79,22 @@ const NERAutocomplete: React.FC<NERAutocompleteProps> = ({
7579
};
7680

7781
return (
78-
<Autocomplete
79-
isOptionEqualToValue={(option, value) => option.id === value.id}
80-
disablePortal
81-
id={id}
82-
onChange={onChange}
83-
options={options}
84-
sx={autocompleteStyle}
85-
size={size}
86-
renderInput={autocompleteRenderInput}
87-
value={value}
88-
filterSelectedOptions={filterSelectedOptions}
89-
ListboxProps={listboxProps}
90-
/>
82+
<>
83+
<Autocomplete
84+
isOptionEqualToValue={(option, value) => option.id === value.id}
85+
disablePortal
86+
id={id}
87+
onChange={onChange}
88+
options={options}
89+
sx={autocompleteStyle}
90+
size={size}
91+
renderInput={autocompleteRenderInput}
92+
value={value}
93+
filterSelectedOptions={filterSelectedOptions}
94+
ListboxProps={listboxProps}
95+
/>
96+
<FormHelperText error={!!errorMessage}>{errorMessage?.message}</FormHelperText>
97+
</>
9198
);
9299
};
93100

src/frontend/src/components/NERFormModal.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ const NERFormModal = ({
4242
disabled={disabled}
4343
showCloseButton={showCloseButton}
4444
>
45-
<form id={formId} onSubmit={handleUseFormSubmit(onSubmitWrapper)}>
45+
<form id={formId} onSubmit={handleUseFormSubmit(onSubmitWrapper)} noValidate>
4646
{children}
4747
</form>
4848
</NERModal>

src/frontend/src/pages/AdminToolsPage/AdminToolsUserManagement.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ const AdminToolsUserManagement: React.FC = () => {
8282
}
8383
};
8484

85-
const userToAutocompleteOption = (user: User): { label: string; id: string } => {
85+
const userToAutocompleteOptionWithRole = (user: User): { label: string; id: string } => {
8686
return { label: `${fullNamePipe(user)} (${user.email}) - ${user.role}`, id: user.userId.toString() };
8787
};
8888

@@ -93,10 +93,10 @@ const AdminToolsUserManagement: React.FC = () => {
9393
<NERAutocomplete
9494
id="users-autocomplete"
9595
onChange={usersSearchOnChange}
96-
options={users.filter((user) => rankUserRole(user.role) < currentUserRank).map(userToAutocompleteOption)}
96+
options={users.filter((user) => rankUserRole(user.role) < currentUserRank).map(userToAutocompleteOptionWithRole)}
9797
size="small"
9898
placeholder="Select a User"
99-
value={user ? userToAutocompleteOption(user) : null}
99+
value={user ? userToAutocompleteOptionWithRole(user) : null}
100100
/>
101101
</Grid>
102102
<Grid item xs={12} md={4}>

src/frontend/src/pages/AdminToolsPage/CreateTeamModal.tsx

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@ import { CreateTeamPayload, useCreateTeam } from '../../hooks/teams.hooks';
66
import ErrorPage from '../ErrorPage';
77
import LoadingIndicator from '../../components/LoadingIndicator';
88
import NERFormModal from '../../components/NERFormModal';
9-
import { FormControl, FormHelperText, FormLabel } from '@mui/material';
9+
import { FormControl, FormLabel } from '@mui/material';
1010
import ReactHookTextField from '../../components/ReactHookTextField';
1111
import { useAllUsers } from '../../hooks/users.hooks';
12-
import { User, isHead } from 'shared';
12+
import { isHead } from 'shared';
1313
import NERAutocomplete from '../../components/NERAutocomplete';
14-
import { fullNamePipe } from '../../utils/pipes';
14+
import { userComparator, userToAutocompleteOption } from '../../utils/teams.utils';
1515

1616
const schema = yup.object().shape({
1717
teamName: yup.string().required('Team Name is Required'),
@@ -25,10 +25,6 @@ interface CreateTeamModalProps {
2525
handleClose: () => void;
2626
}
2727

28-
const userToAutocompleteOption = (user: User): { label: string; id: string } => {
29-
return { label: `${fullNamePipe(user)} (${user.email})`, id: `${user.userId}` };
30-
};
31-
3228
const CreateTeamModal = ({ showModal, handleClose }: CreateTeamModalProps) => {
3329
const { isLoading, mutateAsync } = useCreateTeam();
3430
const { isLoading: allUsersIsLoading, isError: allUsersIsError, error: allUsersError, data: users } = useAllUsers();
@@ -68,7 +64,7 @@ const CreateTeamModal = ({ showModal, handleClose }: CreateTeamModalProps) => {
6864

6965
const headOptions = users
7066
.filter((user) => isHead(user.role))
71-
.sort((a, b) => (a.firstName > b.firstName ? 1 : -1))
67+
.sort(userComparator)
7268
.map(userToAutocompleteOption);
7369

7470
return (
@@ -84,8 +80,7 @@ const CreateTeamModal = ({ showModal, handleClose }: CreateTeamModalProps) => {
8480
>
8581
<FormControl fullWidth>
8682
<FormLabel>Team Name</FormLabel>
87-
<ReactHookTextField name="teamName" control={control} fullWidth />
88-
<FormHelperText error>{errors.teamName?.message}</FormHelperText>
83+
<ReactHookTextField name="teamName" control={control} fullWidth errorMessage={errors.teamName} />
8984
</FormControl>
9085
<FormControl fullWidth>
9186
<FormLabel>Head</FormLabel>
@@ -100,20 +95,25 @@ const CreateTeamModal = ({ showModal, handleClose }: CreateTeamModalProps) => {
10095
id="create-team-head"
10196
size="small"
10297
placeholder="Choose a user"
98+
errorMessage={errors.headId}
10399
/>
104100
)}
105101
/>
106-
<FormHelperText error>{errors.headId?.message}</FormHelperText>
107102
</FormControl>
108103
<FormControl fullWidth>
109104
<FormLabel>Slack Channel ID</FormLabel>
110-
<ReactHookTextField name="slackId" control={control} fullWidth />
111-
<FormHelperText error>{errors.slackId?.message}</FormHelperText>
105+
<ReactHookTextField name="slackId" control={control} fullWidth errorMessage={errors.slackId} />
112106
</FormControl>
113107
<FormControl fullWidth>
114108
<FormLabel>Description</FormLabel>
115-
<ReactHookTextField name="description" control={control} fullWidth multiline rows={5} />
116-
<FormHelperText error>{errors.description?.message}</FormHelperText>
109+
<ReactHookTextField
110+
name="description"
111+
control={control}
112+
fullWidth
113+
multiline
114+
rows={5}
115+
errorMessage={errors.description}
116+
/>
117117
</FormControl>
118118
</NERFormModal>
119119
);

src/frontend/src/pages/AdminToolsPage/TeamsTools.tsx

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -32,28 +32,13 @@ const TeamsTools = () => {
3232
<TableContainer component={Paper}>
3333
<Table>
3434
<TableHead>
35-
<TableCell
36-
align="left"
37-
sx={{ fontSize: '16px', fontWeight: 600, border: '2px solid black' }}
38-
itemType="date"
39-
width="50%"
40-
>
35+
<TableCell align="left" sx={{ fontSize: '16px', fontWeight: 600, border: '2px solid black' }} width="50%">
4136
Team Name
4237
</TableCell>
43-
<TableCell
44-
align="left"
45-
sx={{ fontSize: '16px', fontWeight: 600, border: '2px solid black' }}
46-
itemType="date"
47-
width="30%"
48-
>
38+
<TableCell align="left" sx={{ fontSize: '16px', fontWeight: 600, border: '2px solid black' }} width="30%">
4939
Head
5040
</TableCell>
51-
<TableCell
52-
align="left"
53-
sx={{ fontSize: '16px', fontWeight: 600, border: '2px solid black' }}
54-
itemType="date"
55-
width="30%"
56-
>
41+
<TableCell align="left" sx={{ fontSize: '16px', fontWeight: 600, border: '2px solid black' }} width="30%">
5742
Number of Members
5843
</TableCell>
5944
</TableHead>

src/frontend/src/pages/ProjectDetailPage/ProjectEdit/ProjectEditDetails.tsx

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@ import { User } from 'shared';
22
import { FormControl, FormLabel, Grid } from '@mui/material';
33
import PageBlock from '../../../layouts/PageBlock';
44
import ReactHookTextField from '../../../components/ReactHookTextField';
5-
import { fullNamePipe } from '../../../utils/pipes';
65
import NERAutocomplete from '../../../components/NERAutocomplete';
76
import { ProjectEditFormInput } from './ProjectEditContainer';
87
import { Control, FieldErrorsImpl } from 'react-hook-form';
98
import { AttachMoney } from '@mui/icons-material';
9+
import { userToAutocompleteOption } from '../../../utils/teams.utils';
1010

1111
interface ProjectEditDetailsProps {
1212
users: User[];
@@ -18,11 +18,6 @@ interface ProjectEditDetailsProps {
1818
setProjectLead: (projectLead?: string) => void;
1919
}
2020

21-
const userToAutocompleteOption = (user?: User): { label: string; id: string } => {
22-
if (!user) return { label: '', id: '' };
23-
return { label: `${fullNamePipe(user)} (${user.email}) - ${user.role}`, id: user.userId.toString() };
24-
};
25-
2621
const ProjectEditDetails: React.FC<ProjectEditDetailsProps> = ({
2722
users,
2823
control,

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { Autocomplete, MenuItem, TextField } from '@mui/material';
77
import { GridRenderEditCellParams, useGridApiContext } from '@mui/x-data-grid';
88
import { DatePicker } from '@mui/x-date-pickers';
99
import { UserPreview } from 'shared';
10-
import { getTaskAssigneeOptions, userToAutocompleteOption } from '../../../../utils/task.utils';
10+
import { getTaskAssigneeOptions, taskUserToAutocompleteOption } from '../../../../utils/task.utils';
1111
import ErrorPage from '../../../ErrorPage';
1212

1313
export const TitleEdit = (params: GridRenderEditCellParams) => {
@@ -99,7 +99,7 @@ export const AssigneeEdit = (params: GridRenderEditCellParams) => {
9999

100100
const teamMembers = getTaskAssigneeOptions(teams);
101101

102-
const autocompleteOptions = teamMembers.map(userToAutocompleteOption);
102+
const autocompleteOptions = teamMembers.map(taskUserToAutocompleteOption);
103103

104104
const handleValueChange = (
105105
newValue: {

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ import { isUnderWordCount, countWords } from 'shared';
3333
import { useAuth } from '../../../../hooks/auth.hooks';
3434
import { useState } from 'react';
3535
import { Close, Edit } from '@mui/icons-material';
36-
import { getTaskAssigneeOptions, userToAutocompleteOption } from '../../../../utils/task.utils';
36+
import { getTaskAssigneeOptions, taskUserToAutocompleteOption } from '../../../../utils/task.utils';
3737

3838
interface TaskListNotesModalProps {
3939
task: Task;
@@ -89,7 +89,7 @@ const TaskListNotesModal: React.FC<TaskListNotesModalProps> = ({
8989
});
9090
if (!auth.user) return <LoadingIndicator />;
9191

92-
const options: { label: string; id: number }[] = getTaskAssigneeOptions(teams).map(userToAutocompleteOption);
92+
const options: { label: string; id: number }[] = getTaskAssigneeOptions(teams).map(taskUserToAutocompleteOption);
9393

9494
const dialogWidth: Breakpoint = 'md';
9595
const priorityColor = task.priority === 'HIGH' ? '#ef4345' : task.priority === 'LOW' ? '#00ab41' : '#FFA500';

0 commit comments

Comments
 (0)