Skip to content

Commit fc92838

Browse files
authored
Merge pull request #1687 from Northeastern-Electric-Racing/#1327-WorkPackage-Form-Details
#1327 work package redesign details
2 parents a86471b + 08820cd commit fc92838

5 files changed

Lines changed: 64 additions & 61 deletions

File tree

src/frontend/src/components/ChangeRequestDropdown.tsx

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import { Box, FormControl, FormLabel, MenuItem, Select, SelectChangeEvent } from '@mui/material';
1+
import { Box, FormControl, FormHelperText, FormLabel, MenuItem, Select, SelectChangeEvent } from '@mui/material';
22
import { isWithinInterval, subDays } from 'date-fns';
3-
import { Control, Controller } from 'react-hook-form';
3+
import { Control, Controller, FieldErrors } from 'react-hook-form';
44
import { AuthenticatedUser, ChangeRequest, wbsPipe } from 'shared';
55
import { useAllChangeRequests } from '../hooks/change-requests.hooks';
66
import { useCurrentUser } from '../hooks/users.hooks';
@@ -12,7 +12,7 @@ const getFilteredChangeRequests = (changeRequests: ChangeRequest[], user: Authen
1212
const fiveDaysAgo = subDays(today, 5);
1313

1414
const filteredRequests = changeRequests.filter(
15-
(cr) => cr.dateReviewed && cr.accepted && isWithinInterval(cr.dateReviewed, { start: fiveDaysAgo, end: today })
15+
(cr) => cr.dateImplemented && cr.accepted && isWithinInterval(cr.dateImplemented, { start: fiveDaysAgo, end: today })
1616
);
1717

1818
// The current user's CRs should be at the top
@@ -33,9 +33,11 @@ const getFilteredChangeRequests = (changeRequests: ChangeRequest[], user: Authen
3333
interface ChangeRequestDropdownProps {
3434
control: Control<any, any>;
3535
name: string;
36+
errors: FieldErrors<ChangeRequest>;
37+
changeHeight?: number;
3638
}
3739

38-
const ChangeRequestDropdown = ({ control, name }: ChangeRequestDropdownProps) => {
40+
const ChangeRequestDropdown = ({ control, name, errors, changeHeight = 1 }: ChangeRequestDropdownProps) => {
3941
const user = useCurrentUser();
4042
const { isLoading, data: changeRequests } = useAllChangeRequests();
4143
if (isLoading || !changeRequests) return <LoadingIndicator />;
@@ -48,8 +50,8 @@ const ChangeRequestDropdown = ({ control, name }: ChangeRequestDropdownProps) =>
4850
}));
4951

5052
return (
51-
<Box sx={{ display: 'flex', justifyContent: 'end' }}>
52-
<FormControl>
53+
<Box>
54+
<FormControl fullWidth>
5355
<FormLabel sx={{ alignSelf: 'start' }}>Change Request ID</FormLabel>
5456
<Controller
5557
control={control}
@@ -63,7 +65,8 @@ const ChangeRequestDropdown = ({ control, name }: ChangeRequestDropdownProps) =>
6365
onChange={(event: SelectChangeEvent<number>) => onChange(event.target.value)}
6466
size={'small'}
6567
placeholder={'Change Request Id'}
66-
sx={{ width: 200, textAlign: 'left' }}
68+
sx={{ textAlign: 'left', height: changeHeight }}
69+
error={!!errors.crId}
6770
MenuProps={{
6871
anchorOrigin: {
6972
vertical: 'bottom',
@@ -83,6 +86,7 @@ const ChangeRequestDropdown = ({ control, name }: ChangeRequestDropdownProps) =>
8386
</Select>
8487
)}
8588
/>
89+
<FormHelperText error>{errors.crId?.message}</FormHelperText>
8690
</FormControl>
8791
</Box>
8892
);

src/frontend/src/components/NERAutocomplete.tsx

Lines changed: 23 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,23 +37,16 @@ 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',
4546
backgroundColor: theme.palette.background.default,
4647
width: '100%',
47-
borderRadius: '25px',
4848
border: 0,
49-
'.MuiOutlinedInput-notchedOutline': {
50-
borderColor: 'black',
51-
borderRadius: '25px'
52-
},
53-
'&.Mui-focused .MuiOutlinedInput-notchedOutline': {
54-
borderColor: 'red'
55-
},
49+
borderColor: 'black',
5650
...sx
5751
};
5852

@@ -62,11 +56,7 @@ const NERAutocomplete: React.FC<NERAutocompleteProps> = ({
6256
{...params}
6357
InputProps={{
6458
...params.InputProps,
65-
startAdornment: (
66-
<InputAdornment position="start">
67-
<SearchIcon />
68-
</InputAdornment>
69-
)
59+
sx: { height: '56px' }
7060
}}
7161
placeholder={placeholder}
7262
required
@@ -75,19 +65,22 @@ const NERAutocomplete: React.FC<NERAutocompleteProps> = ({
7565
};
7666

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

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ const ProjectEditContainer: React.FC<ProjectEditContainerProps> = ({ project, ex
174174
<PageLayout
175175
title={`${wbsPipe(project.wbsNum)} - ${project.name}`}
176176
previousPages={[{ name: 'Projects', route: routes.PROJECTS }]}
177-
headerRight={<ChangeRequestDropdown control={control} name="crId" />}
177+
headerRight={<ChangeRequestDropdown control={control} name="crId" errors={errors} />}
178178
>
179179
<form
180180
id="project-edit-form"

src/frontend/src/pages/WorkPackageDetailPage/WorkPackageEditContainer/WorkPackageEditContainer.tsx

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,18 @@ import { useQuery } from '../../../hooks/utils.hooks';
1414
import { Controller, useFieldArray, useForm } from 'react-hook-form';
1515
import { yupResolver } from '@hookform/resolvers/yup';
1616
import * as yup from 'yup';
17-
import { Box, TextField, Autocomplete, FormControl, Typography } from '@mui/material';
17+
import { TextField, Autocomplete, FormControl, Typography } from '@mui/material';
1818
import ReactHookEditableList from '../../../components/ReactHookEditableList';
1919
import { useEditWorkPackage } from '../../../hooks/work-packages.hooks';
20-
import WorkPackageEditDetails from './WorkPackageEditDetails';
20+
import WorkPackageFormDetails from './WorkPackageFormDetails';
2121
import { bulletsToObject, mapBulletsToPayload, startDateTester } from '../../../utils/form';
2222
import NERSuccessButton from '../../../components/NERSuccessButton';
2323
import NERFailButton from '../../../components/NERFailButton';
2424
import { useToast } from '../../../hooks/toasts.hooks';
2525
import { useState } from 'react';
2626
import { useSingleProject } from '../../../hooks/projects.hooks';
2727
import PageLayout from '../../../components/PageLayout';
28-
import ChangeRequestDropdown from '../../../components/ChangeRequestDropdown';
28+
import { Box } from '@mui/system';
2929

3030
const schema = yup.object().shape({
3131
name: yup.string().required('Name is required!'),
@@ -171,7 +171,6 @@ const WorkPackageEditContainer: React.FC<WorkPackageEditContainerProps> = ({ wor
171171
{ name: 'Projects', route: routes.PROJECTS },
172172
{ name: `${projectWbsString} - ${workPackage.projectName}`, route: `${routes.PROJECTS}/${projectWbsString}` }
173173
]}
174-
headerRight={<ChangeRequestDropdown control={control} name="crId" />}
175174
>
176175
<form
177176
id="work-package-edit-form"
@@ -184,7 +183,7 @@ const WorkPackageEditContainer: React.FC<WorkPackageEditContainerProps> = ({ wor
184183
e.key === 'Enter' && e.preventDefault();
185184
}}
186185
>
187-
<WorkPackageEditDetails
186+
<WorkPackageFormDetails
188187
control={control}
189188
errors={errors}
190189
usersForProjectLead={users}

src/frontend/src/pages/WorkPackageDetailPage/WorkPackageEditContainer/WorkPackageEditDetails.tsx renamed to src/frontend/src/pages/WorkPackageDetailPage/WorkPackageEditContainer/WorkPackageFormDetails.tsx

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,14 @@
55

66
import { User, WorkPackageStage } from 'shared';
77
import { fullNamePipe } from '../../../utils/pipes';
8-
import PageBlock from '../../../layouts/PageBlock';
9-
import { FormControl, FormLabel, Grid, MenuItem, TextField } from '@mui/material';
8+
import { FormControl, FormLabel, Grid, MenuItem, TextField, Typography } from '@mui/material';
109
import ReactHookTextField from '../../../components/ReactHookTextField';
1110
import { Control, Controller, FieldErrorsImpl } from 'react-hook-form';
1211
import { DatePicker } from '@mui/x-date-pickers';
1312
import NERAutocomplete from '../../../components/NERAutocomplete';
1413
import { WorkPackageEditFormPayload } from './WorkPackageEditContainer';
14+
import ChangeRequestDropdown from '../../../components/ChangeRequestDropdown';
15+
import { Box } from '@mui/system';
1516

1617
interface Props {
1718
lead?: string;
@@ -24,7 +25,7 @@ interface Props {
2425
errors: Partial<FieldErrorsImpl<WorkPackageEditFormPayload>>;
2526
}
2627

27-
const WorkPackageEditDetails: React.FC<Props> = ({
28+
const WorkPackageFormDetails: React.FC<Props> = ({
2829
lead,
2930
manager,
3031
setManager,
@@ -45,7 +46,7 @@ const WorkPackageEditDetails: React.FC<Props> = ({
4546

4647
const StageSelect = () => (
4748
<FormControl fullWidth>
48-
<FormLabel>Stage Select</FormLabel>
49+
<FormLabel>Work Package Stage</FormLabel>
4950
<Controller
5051
name="stage"
5152
control={control}
@@ -64,9 +65,12 @@ const WorkPackageEditDetails: React.FC<Props> = ({
6465
);
6566

6667
return (
67-
<PageBlock title="Work Package Details">
68-
<Grid container xs={12}>
69-
<Grid item xs={12} md={5} sx={{ mt: 2, mr: 2 }}>
68+
<Box>
69+
<Typography variant="h5" sx={{ marginBottom: '10px', color: 'white' }}>
70+
Project Details
71+
</Typography>
72+
<Grid container spacing={1} xs={12}>
73+
<Grid item xs={12} md={4}>
7074
<FormControl fullWidth>
7175
<FormLabel>Work Package Name</FormLabel>
7276
<ReactHookTextField
@@ -77,7 +81,13 @@ const WorkPackageEditDetails: React.FC<Props> = ({
7781
/>
7882
</FormControl>
7983
</Grid>
80-
<Grid item xs={12} md={2} sx={{ mt: 2, mr: 2 }}>
84+
<Grid item xs={12} md={3}>
85+
<ChangeRequestDropdown control={control} name="crId" errors={errors} changeHeight={56} />
86+
</Grid>
87+
<Grid item xs={12} md={3}>
88+
<StageSelect />
89+
</Grid>
90+
<Grid item xs={12} md={2}>
8191
<FormControl fullWidth sx={{ overflow: 'hidden' }}>
8292
<FormLabel sx={{ whiteSpace: 'noWrap' }}>Start Date (YYYY-MM-DD)</FormLabel>
8393
<Controller
@@ -99,10 +109,7 @@ const WorkPackageEditDetails: React.FC<Props> = ({
99109
/>
100110
</FormControl>
101111
</Grid>
102-
<Grid item xs={12} md={2} sx={{ mt: 2, mr: 2 }}>
103-
<StageSelect />
104-
</Grid>
105-
<Grid item xs={12} md={2} sx={{ mt: 2, mr: 2 }}>
112+
<Grid item xs={12} md={2}>
106113
<FormControl fullWidth>
107114
<FormLabel>Duration</FormLabel>
108115
<ReactHookTextField
@@ -114,10 +121,10 @@ const WorkPackageEditDetails: React.FC<Props> = ({
114121
/>
115122
</FormControl>
116123
</Grid>
117-
<Grid item xs={12} md={6} sx={{ mt: 1 }}>
124+
<Grid item xs={12} md={5}>
118125
<FormLabel> Project Lead</FormLabel>
119126
<NERAutocomplete
120-
sx={{ mt: 1, width: '90%' }}
127+
sx={{ width: '100%' }}
121128
id="project-lead-autocomplete"
122129
onChange={(_event, value) => setLead(value?.id)}
123130
options={usersForProjectLead.map(userToOption)}
@@ -126,10 +133,10 @@ const WorkPackageEditDetails: React.FC<Props> = ({
126133
value={userToOption(usersForProjectLead.find((user) => user.userId.toString() === lead))}
127134
/>
128135
</Grid>
129-
<Grid item xs={12} md={6} sx={{ mt: 1 }}>
136+
<Grid item xs={12} md={5}>
130137
<FormLabel>Project Manager</FormLabel>
131138
<NERAutocomplete
132-
sx={{ mt: 1, width: '90%' }}
139+
sx={{ width: '100%' }}
133140
id="project-manager-autocomplete"
134141
onChange={(_event, value) => setManager(value?.id)}
135142
options={usersForProjectManager.map(userToOption)}
@@ -139,8 +146,8 @@ const WorkPackageEditDetails: React.FC<Props> = ({
139146
/>
140147
</Grid>
141148
</Grid>
142-
</PageBlock>
149+
</Box>
143150
);
144151
};
145152

146-
export default WorkPackageEditDetails;
153+
export default WorkPackageFormDetails;

0 commit comments

Comments
 (0)