Skip to content

Commit fe0d73a

Browse files
authored
Merge pull request #1678 from Northeastern-Electric-Racing/#1322-Redesign-Details-Section-2
#1322 redesigned project details section and created teams dropdown
2 parents e679e5f + 3412909 commit fe0d73a

5 files changed

Lines changed: 145 additions & 68 deletions

File tree

src/frontend/src/components/ChangeRequestDropdown.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@ const ChangeRequestDropdown = ({ control, name }: ChangeRequestDropdownProps) =>
4848
}));
4949

5050
return (
51-
<Box sx={{ display: 'flex', justifyContent: 'end' }}>
52-
<FormControl>
51+
<Box>
52+
<FormControl fullWidth>
5353
<FormLabel sx={{ alignSelf: 'start' }}>Change Request ID</FormLabel>
5454
<Controller
5555
control={control}
@@ -63,7 +63,7 @@ const ChangeRequestDropdown = ({ control, name }: ChangeRequestDropdownProps) =>
6363
onChange={(event: SelectChangeEvent<number>) => onChange(event.target.value)}
6464
size={'small'}
6565
placeholder={'Change Request Id'}
66-
sx={{ width: 200, textAlign: 'left' }}
66+
sx={{ height: 56, width: '100%', textAlign: 'left' }}
6767
MenuProps={{
6868
anchorOrigin: {
6969
vertical: 'bottom',

src/frontend/src/components/NERAutocomplete.tsx

Lines changed: 24 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@
66
import {
77
Autocomplete,
88
AutocompleteRenderInputParams,
9-
InputAdornment,
9+
FormHelperText,
1010
SxProps,
1111
TextField,
1212
Theme,
1313
useTheme
1414
} from '@mui/material';
15-
import SearchIcon from '@mui/icons-material/Search';
1615
import { HTMLAttributes } from 'react';
16+
import { FieldError } from 'react-hook-form';
1717

1818
interface NERAutocompleteProps {
1919
id: string;
@@ -25,6 +25,7 @@ interface NERAutocompleteProps {
2525
value?: { label: string; id: string } | null;
2626
listboxProps?: HTMLAttributes<HTMLUListElement>;
2727
filterSelectedOptions?: boolean;
28+
errorMessage?: FieldError;
2829
}
2930

3031
const NERAutocomplete: React.FC<NERAutocompleteProps> = ({
@@ -36,24 +37,18 @@ const NERAutocomplete: React.FC<NERAutocompleteProps> = ({
3637
sx,
3738
value,
3839
listboxProps,
39-
filterSelectedOptions
40+
filterSelectedOptions,
41+
errorMessage
4042
}) => {
4143
const theme = useTheme();
4244

4345
const autocompleteStyle = {
44-
height: '40px',
46+
height: '50%',
4547
backgroundColor: theme.palette.background.default,
4648
width: '100%',
4749
borderRadius: '25px',
4850
border: 0,
49-
'.MuiOutlinedInput-notchedOutline': {
50-
borderColor: 'black',
51-
borderRadius: '25px'
52-
},
53-
'&.Mui-focused .MuiOutlinedInput-notchedOutline': {
54-
borderColor: 'red'
55-
},
56-
...sx
51+
borderColor: 'black'
5752
};
5853

5954
const autocompleteRenderInput = (params: AutocompleteRenderInputParams) => {
@@ -62,11 +57,7 @@ const NERAutocomplete: React.FC<NERAutocompleteProps> = ({
6257
{...params}
6358
InputProps={{
6459
...params.InputProps,
65-
startAdornment: (
66-
<InputAdornment position="start">
67-
<SearchIcon />
68-
</InputAdornment>
69-
)
60+
sx: { height: '56px' }
7061
}}
7162
placeholder={placeholder}
7263
required
@@ -75,19 +66,22 @@ const NERAutocomplete: React.FC<NERAutocompleteProps> = ({
7566
};
7667

7768
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-
/>
69+
<>
70+
<Autocomplete
71+
isOptionEqualToValue={(option, value) => option.id === value.id}
72+
disablePortal
73+
id={id}
74+
onChange={onChange}
75+
options={options}
76+
sx={autocompleteStyle}
77+
size={size}
78+
renderInput={autocompleteRenderInput}
79+
value={value}
80+
filterSelectedOptions={filterSelectedOptions}
81+
ListboxProps={listboxProps}
82+
/>
83+
<FormHelperText error={!!errorMessage}>{errorMessage?.message}</FormHelperText>
84+
</>
9185
);
9286
};
9387

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import { Box, FormControl, FormLabel, MenuItem, Select, SelectChangeEvent } from '@mui/material';
2+
import { Control, Controller } from 'react-hook-form';
3+
import LoadingIndicator from './LoadingIndicator';
4+
import { useAllTeams } from '../hooks/teams.hooks';
5+
6+
interface TeamDropdownProps {
7+
control: Control<any, any>;
8+
name: string;
9+
}
10+
11+
const TeamDropdown = ({ control, name }: TeamDropdownProps) => {
12+
const { isLoading, data: teams } = useAllTeams();
13+
if (isLoading || !teams) return <LoadingIndicator />;
14+
15+
return (
16+
<Box>
17+
<FormControl fullWidth>
18+
<FormLabel sx={{ alignSelf: 'start' }}>Team</FormLabel>
19+
<Controller
20+
control={control}
21+
name={name}
22+
render={({ field: { onChange, value } }) => (
23+
<Select
24+
id="team-autocomplete"
25+
displayEmpty
26+
renderValue={(value) => teams.find((team) => team.teamId === `${value}`)?.teamName}
27+
value={value}
28+
onChange={(event: SelectChangeEvent<number>) => onChange(event.target.value)}
29+
size={'small'}
30+
placeholder={'Change Team'}
31+
sx={{ height: 56, width: '100%', textAlign: 'left' }}
32+
MenuProps={{
33+
anchorOrigin: {
34+
vertical: 'bottom',
35+
horizontal: 'right'
36+
},
37+
transformOrigin: {
38+
vertical: 'top',
39+
horizontal: 'right'
40+
}
41+
}}
42+
>
43+
{teams.map((team) => {
44+
return (
45+
<MenuItem key={team.teamId} value={team.teamId}>
46+
{team.teamName}
47+
</MenuItem>
48+
);
49+
})}
50+
</Select>
51+
)}
52+
/>
53+
</FormControl>
54+
</Box>
55+
);
56+
};
57+
58+
export default TeamDropdown;

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

Lines changed: 11 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,7 @@ import { useQuery } from '../../../hooks/utils.hooks';
1515
import { useFieldArray, useForm } from 'react-hook-form';
1616
import { yupResolver } from '@hookform/resolvers/yup';
1717
import * as yup from 'yup';
18-
import { Grid, Box, FormControl, Stack, Typography } from '@mui/material';
19-
import ReactHookTextField from '../../../components/ReactHookTextField';
18+
import { Box, Stack, Typography } from '@mui/material';
2019
import ProjectEditDetails from './ProjectEditDetails';
2120
import ReactHookEditableList from '../../../components/ReactHookEditableList';
2221
import { bulletsToObject, mapBulletsToPayload } from '../../../utils/form';
@@ -27,7 +26,6 @@ import LinksEditView from '../../../components/Link/LinksEditView';
2726
import { EditSingleProjectPayload } from '../../../utils/types';
2827
import { useState } from 'react';
2928
import PageLayout from '../../../components/PageLayout';
30-
import ChangeRequestDropdown from '../../../components/ChangeRequestDropdown';
3129

3230
const schema = yup.object().shape({
3331
name: yup.string().required('Name is required!'),
@@ -173,7 +171,16 @@ const ProjectEditContainer: React.FC<ProjectEditContainerProps> = ({ project, ex
173171
<PageLayout
174172
title={`${wbsPipe(project.wbsNum)} - ${project.name}`}
175173
previousPages={[{ name: 'Projects', route: routes.PROJECTS }]}
176-
headerRight={<ChangeRequestDropdown control={control} name="crId" />}
174+
headerRight={
175+
<Box textAlign="right">
176+
<NERFailButton variant="contained" onClick={exitEditMode} sx={{ mx: 1 }}>
177+
Cancel
178+
</NERFailButton>
179+
<NERSuccessButton variant="contained" type="submit" sx={{ mx: 1 }}>
180+
Submit
181+
</NERSuccessButton>
182+
</Box>
183+
}
177184
>
178185
<form
179186
id="project-edit-form"
@@ -195,20 +202,6 @@ const ProjectEditContainer: React.FC<ProjectEditContainerProps> = ({ project, ex
195202
setProjectLead={setProjectLeadId}
196203
setProjectManager={setprojectManagerId}
197204
/>
198-
<PageBlock title="Project Summary">
199-
<Grid item sx={{ mt: 2 }}>
200-
<FormControl fullWidth>
201-
<ReactHookTextField
202-
name="summary"
203-
control={control}
204-
placeholder="Summary"
205-
multiline={true}
206-
rows={5}
207-
errorMessage={errors.summary}
208-
/>
209-
</FormControl>
210-
</Grid>
211-
</PageBlock>
212205
<PageBlock title="Links">
213206
<LinksEditView watch={watch} ls={links} register={register} append={appendLink} remove={removeLink} />
214207
</PageBlock>
@@ -258,14 +251,6 @@ const ProjectEditContainer: React.FC<ProjectEditContainerProps> = ({ project, ex
258251
/>
259252
</Box>
260253
</Stack>
261-
<Box textAlign="right" sx={{ my: 2 }}>
262-
<NERFailButton variant="contained" onClick={exitEditMode} sx={{ mx: 1 }}>
263-
Cancel
264-
</NERFailButton>
265-
<NERSuccessButton variant="contained" type="submit" sx={{ mx: 1 }}>
266-
Submit
267-
</NERSuccessButton>
268-
</Box>
269254
</form>
270255
</PageLayout>
271256
);

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

Lines changed: 49 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
import { User } from 'shared';
2-
import { FormControl, FormLabel, Grid } from '@mui/material';
3-
import PageBlock from '../../../layouts/PageBlock';
2+
import { Box, FormControl, FormLabel, Grid, Typography } from '@mui/material';
43
import ReactHookTextField from '../../../components/ReactHookTextField';
54
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 ChangeRequestDropdown from '../../../components/ChangeRequestDropdown';
10+
import TeamDropdown from '../../../components/TeamsDropdown';
1011

1112
interface ProjectEditDetailsProps {
1213
users: User[];
@@ -33,9 +34,12 @@ const ProjectEditDetails: React.FC<ProjectEditDetailsProps> = ({
3334
setProjectManager
3435
}) => {
3536
return (
36-
<PageBlock title="Project Details">
37-
<Grid container spacing={2}>
38-
<Grid item xs={8}>
37+
<Box>
38+
<Typography variant="h5" sx={{ marginBottom: '10px' }}>
39+
Project Details
40+
</Typography>
41+
<Grid container spacing={3}>
42+
<Grid item lg={2.4} md={6} xs={12}>
3943
<FormControl fullWidth>
4044
<FormLabel>Project Name</FormLabel>
4145
<ReactHookTextField
@@ -46,7 +50,28 @@ const ProjectEditDetails: React.FC<ProjectEditDetailsProps> = ({
4650
/>
4751
</FormControl>
4852
</Grid>
49-
<Grid item xs={4}>
53+
<Grid item lg={2.4} md={6} xs={12}>
54+
<FormControl fullWidth>
55+
<ChangeRequestDropdown control={control} name="crId" />
56+
</FormControl>
57+
</Grid>
58+
<Grid item lg={2.4} md={6} xs={12}>
59+
<FormControl fullWidth>
60+
<FormLabel>Car Number</FormLabel>
61+
<ReactHookTextField
62+
name="car-number"
63+
control={control}
64+
placeholder="Enter a car number..."
65+
errorMessage={errors.name}
66+
/>
67+
</FormControl>
68+
</Grid>
69+
<Grid item lg={2.4} md={6} xs={12}>
70+
<FormControl fullWidth>
71+
<TeamDropdown control={control} name="teamId" />
72+
</FormControl>
73+
</Grid>
74+
<Grid item lg={2.4} md={6} xs={12}>
5075
<FormControl fullWidth>
5176
<FormLabel>Budget</FormLabel>
5277
<ReactHookTextField
@@ -59,7 +84,9 @@ const ProjectEditDetails: React.FC<ProjectEditDetailsProps> = ({
5984
/>
6085
</FormControl>
6186
</Grid>
62-
<Grid item xs={12} md={6} sx={{ mt: 1 }}>
87+
</Grid>
88+
<Grid container spacing={2}>
89+
<Grid item lg={6} md={12} xs={12} mt={{ xs: 3, md: 3, lg: 2 }}>
6390
<FormLabel>Project Lead</FormLabel>
6491
<NERAutocomplete
6592
id="users-autocomplete"
@@ -70,7 +97,7 @@ const ProjectEditDetails: React.FC<ProjectEditDetailsProps> = ({
7097
value={userToAutocompleteOption(users.find((user) => user.userId.toString() === projectLead))}
7198
/>
7299
</Grid>
73-
<Grid item xs={12} md={6} sx={{ mt: 1 }}>
100+
<Grid item lg={6} md={12} xs={12} mt={{ xs: 0, md: 0, lg: 2 }}>
74101
<FormLabel>Project Manager</FormLabel>
75102
<NERAutocomplete
76103
id="users-autocomplete"
@@ -81,8 +108,21 @@ const ProjectEditDetails: React.FC<ProjectEditDetailsProps> = ({
81108
value={userToAutocompleteOption(users.find((user) => user.userId.toString() === projectManager))}
82109
/>
83110
</Grid>
111+
<Grid item lg={12} md={12} xs={12}>
112+
<FormControl fullWidth>
113+
<FormLabel>Project Summary</FormLabel>
114+
<ReactHookTextField
115+
name="summary"
116+
control={control}
117+
type="number"
118+
placeholder="Enter a summmary..."
119+
multiline={true}
120+
rows={5}
121+
/>
122+
</FormControl>
123+
</Grid>
84124
</Grid>
85-
</PageBlock>
125+
</Box>
86126
);
87127
};
88128

0 commit comments

Comments
 (0)