Skip to content

Commit 88aa4ae

Browse files
authored
Merge pull request #1717 from Northeastern-Electric-Racing/#1637-Change-Request-Overview-Page-Redesign
#1637: reformatted cards on overiew page
2 parents 201bf2d + 090ac05 commit 88aa4ae

3 files changed

Lines changed: 135 additions & 109 deletions

File tree

src/frontend/src/components/ChangeRequestDetailCard.tsx

Lines changed: 102 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -3,96 +3,111 @@
33
* See the LICENSE file in the repository root folder for details.
44
*/
55

6-
import { Card, CardContent, Grid, Typography } from '@mui/material';
6+
import { Card, CardContent, Grid, Typography, useTheme } from '@mui/material';
77
import Chip from '@mui/material/Chip';
8-
import { green, blue, red, grey, orange } from '@mui/material/colors';
8+
import { green, blue, red, grey, purple } from '@mui/material/colors';
99
import { Box, Stack } from '@mui/system';
1010
import { Link } from '@mui/material';
1111
import {
1212
ActivationChangeRequest,
1313
ChangeRequest,
14+
ChangeRequestStatus,
1415
ChangeRequestType,
15-
StageGateChangeRequest,
1616
StandardChangeRequest,
1717
wbsPipe
1818
} from 'shared';
1919
import { routes } from '../utils/routes';
2020
import { Link as RouterLink } from 'react-router-dom';
21-
import { datePipe, fullNamePipe } from '../utils/pipes';
22-
import { Cancel, Construction, DateRange, Description, DoneAll, Person, Start, Work } from '@mui/icons-material';
23-
import { ChangeRequestTypeTextPipe } from '../utils/enum-pipes';
21+
import { fullNamePipe } from '../utils/pipes';
22+
import { ChangeRequestTypeTextPipe, ChangeRequestStatusTextPipe } from '../utils/enum-pipes';
2423

25-
const determineChangeRequestTypeView = (cr: ChangeRequest) => {
26-
switch (cr.type) {
27-
case 'STAGE_GATE':
28-
return <StageGateCardDetails cr={cr as StageGateChangeRequest} />;
29-
case 'ACTIVATION':
30-
return <ActivationCardDetails cr={cr as ActivationChangeRequest} />;
31-
default:
32-
return <StandardCardDetails cr={cr as StandardChangeRequest} />;
33-
}
34-
};
35-
36-
const determineChangeRequestPillColor = (type: ChangeRequestType) => {
37-
switch (type) {
38-
case 'STAGE_GATE':
39-
return orange[900];
40-
case 'ACTIVATION':
41-
return green[600];
42-
case 'DEFINITION_CHANGE':
24+
const determineChangeRequestStatusPillColor = (status: ChangeRequestStatus) => {
25+
switch (status) {
26+
case ChangeRequestStatus.Implemented:
4327
return blue[600];
44-
case 'ISSUE':
28+
case ChangeRequestStatus.Accepted:
29+
return green[600];
30+
case ChangeRequestStatus.Denied:
4531
return red[400];
32+
case ChangeRequestStatus.Open:
33+
return purple[400];
4634
default:
4735
return grey[500];
4836
}
4937
};
5038

51-
const StandardCardDetails = ({ cr }: { cr: StandardChangeRequest }) => {
39+
const ChangeRequestTypePill = ({ type }: { type: ChangeRequestType }) => {
5240
return (
53-
<Grid container mt={1} ml={'2px'}>
54-
<Grid item>
55-
<Description sx={{ ml: '-4px' }} display={'inline'} />
56-
</Grid>
57-
<Grid item xs>
58-
<Typography ml={'4px'} display={'inline'}>
59-
{cr.what}
60-
</Typography>
61-
</Grid>
62-
</Grid>
41+
<Chip
42+
size="small"
43+
label={ChangeRequestTypeTextPipe(type)}
44+
variant="filled"
45+
sx={{
46+
fontSize: 12,
47+
color: 'white',
48+
backgroundColor: red[600],
49+
width: 100
50+
}}
51+
/>
6352
);
6453
};
6554

66-
const StageGateCardDetails = ({ cr }: { cr: StageGateChangeRequest }) => {
55+
const ChangeRequestStatusPill = ({ status }: { status: ChangeRequestStatus }) => {
56+
const statusPillColor = determineChangeRequestStatusPillColor(status);
6757
return (
68-
<Box ml={-1}>
69-
{cr.confirmDone ? (
70-
<Chip icon={<DoneAll />} label={'Done'} sx={{ backgroundColor: 'transparent' }} />
71-
) : (
72-
<Chip icon={<Cancel />} label={'Not Done'} sx={{ backgroundColor: 'transparent' }} />
73-
)}
74-
</Box>
58+
<Chip
59+
size="small"
60+
label={ChangeRequestStatusTextPipe(status)}
61+
variant="filled"
62+
sx={{
63+
fontSize: 12,
64+
color: 'white',
65+
backgroundColor: statusPillColor,
66+
width: 100
67+
}}
68+
/>
7569
);
7670
};
7771

78-
const ActivationCardDetails = ({ cr }: { cr: ActivationChangeRequest }) => {
72+
const CRCardDescription = ({ cr }: { cr: ChangeRequest }) => {
73+
const theme = useTheme();
74+
const isAccepted = cr.status === ChangeRequestStatus.Implemented || cr.status === ChangeRequestStatus.Accepted;
75+
const isStageGate = cr.type === ChangeRequestType.StageGate;
76+
const isActivation = cr.type === ChangeRequestType.Activation;
7977
return (
80-
<Box>
81-
<Stack direction="row">
82-
<Chip
83-
icon={<Construction />}
84-
label={fullNamePipe(cr.projectLead)}
85-
sx={{ backgroundColor: 'transparent', mr: 2, ml: -1, maxWidth: '150' }}
86-
/>
87-
<Chip
88-
icon={<Work />}
89-
label={fullNamePipe(cr.projectManager)}
90-
sx={{ backgroundColor: 'transparent', maxWidth: '150' }}
91-
/>
92-
</Stack>
93-
<Stack direction="row" justifyContent={'space-between'}>
94-
<Chip icon={<Start />} label={datePipe(cr.startDate)} sx={{ backgroundColor: 'transparent', ml: -1 }} />
95-
</Stack>
78+
<Box
79+
sx={{
80+
backgroundColor: theme.palette.divider,
81+
width: '100%',
82+
height: 75,
83+
borderRadius: 1,
84+
padding: 1,
85+
overflow: 'hidden',
86+
textOverflow: 'ellipsis'
87+
}}
88+
>
89+
<Typography variant="body1" fontSize={14}>
90+
{isAccepted ? (
91+
cr.reviewNotes ? (
92+
'Review Notes: ' + cr.reviewNotes
93+
) : (
94+
'No review notes'
95+
)
96+
) : isActivation ? (
97+
<div>
98+
<Typography variant="body1" fontSize={14}>
99+
Lead: {fullNamePipe((cr as ActivationChangeRequest).projectLead)}
100+
</Typography>
101+
<Typography variant="body1" fontSize={14}>
102+
Manager: {fullNamePipe((cr as ActivationChangeRequest).projectManager)}
103+
</Typography>
104+
</div>
105+
) : isStageGate ? (
106+
'Stage Gate ' + wbsPipe(cr.wbsNum) + ' - ' + cr.wbsName
107+
) : (
108+
(cr as StandardChangeRequest).what
109+
)}
110+
</Typography>
96111
</Box>
97112
);
98113
};
@@ -101,49 +116,41 @@ interface ChangeRequestDetailCardProps {
101116
changeRequest: ChangeRequest;
102117
}
103118

104-
// Convert work package stage into badge for display
105119
const ChangeRequestDetailCard: React.FC<ChangeRequestDetailCardProps> = ({ changeRequest }) => {
106-
const ChangeRequestTypeView = () => determineChangeRequestTypeView(changeRequest);
107-
const pillColor = determineChangeRequestPillColor(changeRequest.type);
108120
return (
109-
<Card sx={{ minWidth: 300, width: 300, mr: 1, mb: 1, borderRadius: 5 }}>
121+
<Card sx={{ width: 325, mr: 2, borderRadius: 3, mb: 2 }}>
110122
<CardContent>
111-
<Grid container justifyContent="space-between" alignItems="center">
112-
<Grid item>
113-
<Link component={RouterLink} to={`${routes.CHANGE_REQUESTS}/${changeRequest.crId}`} noWrap>
123+
<Grid container justifyContent="space-between" alignItems="flex-start">
124+
<Grid item xs mb={1} mt={-1.5}>
125+
<Link
126+
underline={'none'}
127+
color={'inherit'}
128+
component={RouterLink}
129+
to={`${routes.CHANGE_REQUESTS}/${changeRequest.crId}`}
130+
>
114131
<Typography variant="h6" sx={{ mb: 0.5 }}>
115-
{'CR #' + changeRequest.crId}
132+
{'Change Request #' + changeRequest.crId}
116133
</Typography>
117134
</Link>
135+
<Stack direction={'column'} maxWidth={'195px'}>
136+
<Typography variant="body1" sx={{ mr: 2, fontWeight: 'bold', fontSize: 13 }}>
137+
From: {fullNamePipe(changeRequest.submitter)}
138+
</Typography>
139+
<Typography fontWeight={'bold'} fontSize={12} noWrap>
140+
<Link component={RouterLink} to={`${routes.PROJECTS}/${wbsPipe(changeRequest.wbsNum)}`}>
141+
{wbsPipe(changeRequest.wbsNum)} {changeRequest.wbsName}
142+
</Link>
143+
</Typography>
144+
</Stack>
118145
</Grid>
119-
<Grid item display="flex" justifyContent="flex-end">
120-
<Chip
121-
size="small"
122-
label={ChangeRequestTypeTextPipe(changeRequest.type)}
123-
variant="outlined"
124-
sx={{
125-
fontSize: 12,
126-
color: pillColor,
127-
borderColor: pillColor,
128-
mb: 0.5
129-
}}
130-
/>
146+
<Grid item xs="auto" mb={1}>
147+
<Stack direction={'column'} spacing={1}>
148+
<ChangeRequestTypePill type={changeRequest.type} />
149+
<ChangeRequestStatusPill status={changeRequest.status} />
150+
</Stack>
131151
</Grid>
132152
</Grid>
133-
<Stack direction="row">
134-
<Chip
135-
icon={<Person />}
136-
label={fullNamePipe(changeRequest.submitter)}
137-
sx={{ mr: 2, ml: -1, backgroundColor: 'transparent', maxWidth: '150' }}
138-
/>
139-
<Chip icon={<DateRange />} label={datePipe(changeRequest.dateSubmitted)} sx={{ backgroundColor: 'transparent' }} />
140-
</Stack>
141-
<Typography fontWeight={'regular'} variant="h6" fontSize={16} noWrap>
142-
<Link component={RouterLink} to={`${routes.PROJECTS}/${wbsPipe(changeRequest.wbsNum)}`}>
143-
{wbsPipe(changeRequest.wbsNum)} - {changeRequest.wbsName}
144-
</Link>
145-
</Typography>
146-
<ChangeRequestTypeView />
153+
<CRCardDescription cr={changeRequest} />
147154
</CardContent>
148155
</Card>
149156
);

src/frontend/src/pages/ChangeRequestsPage/ChangeRequestsOverview.tsx

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,11 @@
33
* See the LICENSE file in the repository root folder for details.
44
*/
55

6-
import { Box, Grid, useTheme } from '@mui/material';
6+
import { Box, Grid, Typography, useTheme } from '@mui/material';
77
import { useAllChangeRequests } from '../../hooks/change-requests.hooks';
88
import LoadingIndicator from '../../components/LoadingIndicator';
99
import ErrorPage from '../ErrorPage';
1010
import { isLeadership, isHead, ChangeRequest, Project, WorkPackage, equalsWbsNumber } from 'shared';
11-
import PageBlock from '../../layouts/PageBlock';
1211
import { useAllProjects } from '../../hooks/projects.hooks';
1312
import { useAllWorkPackages } from '../../hooks/work-packages.hooks';
1413
import ChangeRequestDetailCard from '../../components/ChangeRequestDetailCard';
@@ -108,19 +107,26 @@ const ChangeRequestsOverview: React.FC = () => {
108107
</Box>
109108
);
110109

110+
const renderChangeRequests = (title: string, crList: ChangeRequest[], emptyMessage: string) => {
111+
return (
112+
<>
113+
<Typography variant="h5" gutterBottom>
114+
{title}
115+
</Typography>
116+
{crList.length > 0 ? (
117+
<Grid container>{displayCRCards(crList)}</Grid>
118+
) : (
119+
<Typography gutterBottom>{emptyMessage}</Typography>
120+
)}
121+
</>
122+
);
123+
};
124+
111125
return (
112126
<Box>
113-
{showToReview && (
114-
<PageBlock title={'To Review'} headerRight={`${crToReview.length} Left`}>
115-
<Grid container>{displayCRCards(crToReview)}</Grid>
116-
</PageBlock>
117-
)}
118-
<PageBlock title={'My Un-reviewed Change Requests'} headerRight={`${crUnreviewed.length} Left`}>
119-
<Grid container>{displayCRCards(crUnreviewed)}</Grid>
120-
</PageBlock>
121-
<PageBlock title={'My Recently Approved Change Requests'} headerRight={`${crApproved.length} Left`} defaultClosed>
122-
<Grid container>{displayCRCards(crApproved)}</Grid>
123-
</PageBlock>
127+
{showToReview && renderChangeRequests('To Review', crToReview, 'No change requests to review')}
128+
{renderChangeRequests('My Un-reviewed Change Requests', crUnreviewed, 'No un-reviewed change requests')}
129+
{renderChangeRequests('My Recently Approved Change Requests', crApproved, 'No recently approved change requests')}
124130
</Box>
125131
);
126132
};

src/frontend/src/utils/enum-pipes.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
*/
55

66
import { yellow, green, blue, purple, grey } from '@mui/material/colors';
7-
import { ChangeRequestType, WorkPackageStage } from 'shared';
7+
import { ChangeRequestStatus, ChangeRequestType, WorkPackageStage } from 'shared';
88

99
// maps stage to the desired color
1010
export const WorkPackageStageColorPipe: (stage: WorkPackageStage | undefined) => string = (stage) => {
@@ -52,3 +52,16 @@ export const ChangeRequestTypeTextPipe: (type: ChangeRequestType) => string = (t
5252
return 'Other';
5353
}
5454
};
55+
56+
export const ChangeRequestStatusTextPipe: (status: ChangeRequestStatus) => string = (status) => {
57+
switch (status) {
58+
case ChangeRequestStatus.Implemented:
59+
return 'Implemented';
60+
case ChangeRequestStatus.Accepted:
61+
return 'Accepted';
62+
case ChangeRequestStatus.Denied:
63+
return 'Denied';
64+
case ChangeRequestStatus.Open:
65+
return 'Open';
66+
}
67+
};

0 commit comments

Comments
 (0)