Skip to content

Commit 4dc865e

Browse files
committed
#1650 - rough draft
1 parent 7aec28c commit 4dc865e

11 files changed

Lines changed: 130 additions & 192 deletions

File tree

src/frontend/src/components/ChangeRequestDetailCard.tsx

Lines changed: 2 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@
44
*/
55

66
import { Card, CardContent, Grid, Typography, useTheme } from '@mui/material';
7-
import Chip from '@mui/material/Chip';
8-
import { green, blue, red, grey, purple } from '@mui/material/colors';
97
import { Box, Stack } from '@mui/system';
108
import { Link } from '@mui/material';
119
import {
@@ -19,55 +17,8 @@ import {
1917
import { routes } from '../utils/routes';
2018
import { Link as RouterLink } from 'react-router-dom';
2119
import { fullNamePipe } from '../utils/pipes';
22-
import { ChangeRequestTypeTextPipe, ChangeRequestStatusTextPipe } from '../utils/enum-pipes';
23-
24-
const determineChangeRequestStatusPillColor = (status: ChangeRequestStatus) => {
25-
switch (status) {
26-
case ChangeRequestStatus.Implemented:
27-
return blue[600];
28-
case ChangeRequestStatus.Accepted:
29-
return green[600];
30-
case ChangeRequestStatus.Denied:
31-
return red[400];
32-
case ChangeRequestStatus.Open:
33-
return purple[400];
34-
default:
35-
return grey[500];
36-
}
37-
};
38-
39-
const ChangeRequestTypePill = ({ type }: { type: ChangeRequestType }) => {
40-
return (
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-
/>
52-
);
53-
};
54-
55-
const ChangeRequestStatusPill = ({ status }: { status: ChangeRequestStatus }) => {
56-
const statusPillColor = determineChangeRequestStatusPillColor(status);
57-
return (
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-
/>
69-
);
70-
};
20+
import ChangeRequestTypePill from './ChangeRequestTypePill';
21+
import ChangeRequestStatusPill from './ChangeRequestStatusPill';
7122

7223
const CRCardDescription = ({ cr }: { cr: ChangeRequest }) => {
7324
const theme = useTheme();

src/frontend/src/components/InfoBlock.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,24 @@
55

66
import Typography from '@mui/material/Typography';
77
import { Grid } from '@mui/material';
8+
import { ReactNode } from 'react';
89

910
interface InfoBlockProps {
1011
title: string;
12+
icon?: ReactNode;
1113
}
1214

1315
/**
1416
* Custom component for a consistent page-building block.
1517
* @param title The title of the block on the page
1618
* @param children The children of the block
1719
*/
18-
const InfoBlock: React.FC<InfoBlockProps> = ({ title, children }) => {
20+
const InfoBlock: React.FC<InfoBlockProps> = ({ title, icon, children }) => {
1921
return (
2022
<Grid container spacing={1}>
21-
<Grid item xs={12}>
23+
<Grid item xs={12} display="flex" gap="5px" alignItems="center">
2224
<Typography sx={{ fontWeight: 'bold', fontSize: '19px' }}>{title}</Typography>
25+
{icon}
2326
</Grid>
2427
<Grid item xs={12}>
2528
{children}

src/frontend/src/components/PageLayout.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { Box } from '@mui/system';
1111

1212
interface PageLayoutProps {
1313
title?: string;
14+
chips?: ReactNode;
1415
hidePageTitle?: boolean;
1516
previousPages?: LinkItem[];
1617
headerRight?: ReactNode;
@@ -21,6 +22,7 @@ interface PageLayoutProps {
2122
const PageLayout: React.FC<PageLayoutProps> = ({
2223
children,
2324
title,
25+
chips,
2426
hidePageTitle = false,
2527
previousPages = [],
2628
headerRight,
@@ -33,7 +35,9 @@ const PageLayout: React.FC<PageLayoutProps> = ({
3335
<title>{`FinishLine ${title && `| ${title}`}`}</title>
3436
<meta name="description" content="FinishLine Project Management Dashboard" />
3537
</Helmet>
36-
{!hidePageTitle && title && <PageTitle sticky={stickyHeader} {...{ title, previousPages, headerRight, tabs }} />}
38+
{!hidePageTitle && title && (
39+
<PageTitle sticky={stickyHeader} {...{ title, chips, previousPages, headerRight, tabs }} />
40+
)}
3741
{children}
3842
</Box>
3943
);

src/frontend/src/layouts/PageTitle/PageTitle.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import PageBreadcrumbs from './PageBreadcrumbs';
1010

1111
interface PageTitleProps {
1212
title: string;
13+
chips?: ReactNode;
1314
previousPages: LinkItem[];
1415
headerRight?: ReactNode;
1516
tabs?: ReactElement;
@@ -23,7 +24,7 @@ interface PageTitleProps {
2324
* @param headerRight The button to display on the right side of the page title
2425
* @param tabs The tabs on the page to display.
2526
*/
26-
const PageTitle: React.FC<PageTitleProps> = ({ title, previousPages, headerRight, tabs, sticky }) => {
27+
const PageTitle: React.FC<PageTitleProps> = ({ title, chips, previousPages, headerRight, tabs, sticky }) => {
2728
const theme = useTheme();
2829

2930
return (
@@ -40,12 +41,13 @@ const PageTitle: React.FC<PageTitleProps> = ({ title, previousPages, headerRight
4041
bgcolor={theme.palette.background.default}
4142
>
4243
<Grid container>
43-
<Grid item xs={6} md={4}>
44+
<Grid item xs={6} md={tabs ? 4 : 8} display="flex" alignItems={'center'}>
4445
<Typography variant="h4" fontSize={30}>
4546
{title}
4647
</Typography>
48+
{chips}
4749
</Grid>
48-
<Grid item xs={0} md={4} sx={{ display: { xs: 'none', md: 'block' } }}>
50+
<Grid item xs={0} md={tabs ? 4 : 0} sx={{ display: { xs: 'none', md: 'block' } }}>
4951
{tabs}
5052
</Grid>
5153
<Grid item xs={6} md={4} textAlign={['left', 'right']}>

src/frontend/src/pages/ChangeRequestDetailPage/ActivationDetails.tsx

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,26 +8,29 @@ import { datePipe, fullNamePipe } from '../../utils/pipes';
88
import Grid from '@mui/material/Grid';
99
import Typography from '@mui/material/Typography';
1010
import InfoBlock from '../../components/InfoBlock';
11+
import HandymanIcon from '@mui/icons-material/Handyman';
12+
import WorkIcon from '@mui/icons-material/Work';
13+
import CalendarTodayIcon from '@mui/icons-material/CalendarToday';
1114

1215
interface ActivationDetailsProps {
1316
cr: ActivationChangeRequest;
1417
}
1518

1619
const ActivationDetails: React.FC<ActivationDetailsProps> = ({ cr }) => {
1720
return (
18-
<Grid container>
19-
<Grid item xs={6} md={2}>
20-
<InfoBlock title={'Project Lead'}>
21+
<Grid container rowSpacing={'10px'} mb="10px">
22+
<Grid item xs={6} md={3}>
23+
<InfoBlock title={'Project Lead'} icon={<HandymanIcon />}>
2124
<Typography>{fullNamePipe(cr.projectLead)}</Typography>
2225
</InfoBlock>
2326
</Grid>
24-
<Grid item xs={6} md={2}>
25-
<InfoBlock title={'Project Manager'}>
27+
<Grid item xs={6} md={3}>
28+
<InfoBlock title={'Project Manager'} icon={<WorkIcon />}>
2629
<Typography>{fullNamePipe(cr.projectManager)}</Typography>
2730
</InfoBlock>
2831
</Grid>
29-
<Grid item xs={6} md={2}>
30-
<InfoBlock title={'Start Date'}>
32+
<Grid item xs={6} md={3}>
33+
<InfoBlock title={'Start Date'} icon={<CalendarTodayIcon />}>
3134
<Typography>{datePipe(cr.startDate)}</Typography>
3235
</InfoBlock>
3336
</Grid>

src/frontend/src/pages/ChangeRequestDetailPage/ChangeRequestDetailsView.tsx

Lines changed: 36 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -5,57 +5,36 @@
55

66
import { ReactElement, useState } from 'react';
77
import { Link as RouterLink } from 'react-router-dom';
8-
import {
9-
ActivationChangeRequest,
10-
ChangeRequest,
11-
ChangeRequestType,
12-
StageGateChangeRequest,
13-
StandardChangeRequest,
14-
isProject
15-
} from 'shared';
8+
import { ActivationChangeRequest, ChangeRequest, ChangeRequestType, StandardChangeRequest, isProject } from 'shared';
169
import { routes } from '../../utils/routes';
1710
import { datePipe, fullNamePipe, wbsPipe } from '../../utils/pipes';
1811
import ActivationDetails from './ActivationDetails';
19-
import StageGateDetails from './StageGateDetails';
2012
import ImplementedChangesList from './ImplementedChangesList';
2113
import StandardDetails from './StandardDetails';
2214
import ReviewChangeRequest from './ReviewChangeRequest';
2315
import ReviewNotes from './ReviewNotes';
2416
import ProposedSolutionsList from './ProposedSolutionsList';
25-
import { Grid, Typography, Link } from '@mui/material';
17+
import { Grid, Typography, Link, Box } from '@mui/material';
2618
import DeleteChangeRequest from './DeleteChangeRequest';
2719
import { useSingleProject } from '../../hooks/projects.hooks';
2820
import LoadingIndicator from '../../components/LoadingIndicator';
2921
import ErrorPage from '../ErrorPage';
3022
import PageLayout from '../../components/PageLayout';
3123
import ChangeRequestActionMenu from './ChangeRequestActionMenu';
3224
import OtherChangeRequestsPopupTabs from './OtherChangeRequestsPopupTabs';
25+
import ChangeRequestTypePill from '../../components/ChangeRequestTypePill';
26+
import ChangeRequestStatusPill from '../../components/ChangeRequestStatusPill';
3327

3428
const buildDetails = (cr: ChangeRequest): ReactElement => {
3529
switch (cr.type) {
3630
case ChangeRequestType.Activation:
3731
return <ActivationDetails cr={cr as ActivationChangeRequest} />;
3832
case ChangeRequestType.StageGate:
39-
return <StageGateDetails cr={cr as StageGateChangeRequest} />;
33+
return <></>;
4034
default:
4135
return <StandardDetails cr={cr as StandardChangeRequest} />;
4236
}
4337
};
44-
45-
const buildProposedSolutions = (cr: ChangeRequest): ReactElement => {
46-
if (cr.type !== ChangeRequestType.Activation && cr.type !== ChangeRequestType.StageGate) {
47-
return (
48-
<ProposedSolutionsList
49-
proposedSolutions={(cr as StandardChangeRequest).proposedSolutions}
50-
crReviewed={cr.accepted}
51-
crId={cr.crId}
52-
/>
53-
);
54-
} else {
55-
return <></>;
56-
}
57-
};
58-
5938
interface ChangeRequestDetailsProps {
6039
isUserAllowedToReview: boolean;
6140
isUserAllowedToImplement: boolean;
@@ -90,9 +69,18 @@ const ChangeRequestDetailsView: React.FC<ChangeRequestDetailsProps> = ({
9069

9170
const { name: projectName } = project;
9271

72+
const isStandard =
73+
changeRequest.type !== ChangeRequestType.Activation && changeRequest.type !== ChangeRequestType.StageGate;
74+
9375
return (
9476
<PageLayout
9577
title={`Change Request #${changeRequest.crId}`}
78+
chips={
79+
<Box display="flex" mx="20px" gap="20px">
80+
<ChangeRequestTypePill type={changeRequest.type} />
81+
<ChangeRequestStatusPill status={changeRequest.status} />
82+
</Box>
83+
}
9684
previousPages={[{ name: 'Change Requests', route: routes.CHANGE_REQUESTS }]}
9785
headerRight={
9886
<ChangeRequestActionMenu
@@ -124,24 +112,30 @@ const ChangeRequestDetailsView: React.FC<ChangeRequestDetailsProps> = ({
124112
</Grid>
125113
</Grid>
126114
<Grid container rowSpacing={2} columnSpacing={2}>
127-
<Grid item xs={12}>
115+
<Grid container item xs={isStandard ? 7 : 12}>
128116
{buildDetails(changeRequest)}
117+
<Grid item md={isStandard ? 12 : 5}>
118+
<ReviewNotes
119+
reviewer={changeRequest.reviewer}
120+
reviewNotes={changeRequest.reviewNotes}
121+
dateReviewed={changeRequest.dateReviewed}
122+
/>
123+
</Grid>
124+
<Grid item md={isStandard ? 12 : 6}>
125+
<ImplementedChangesList
126+
changes={changeRequest.implementedChanges || []}
127+
overallDateImplemented={changeRequest.dateImplemented}
128+
/>
129+
</Grid>
129130
</Grid>
130-
<Grid item xs={12}>
131-
{buildProposedSolutions(changeRequest)}
132-
</Grid>
133-
<Grid item md={5}>
134-
<ReviewNotes
135-
reviewer={changeRequest.reviewer}
136-
reviewNotes={changeRequest.reviewNotes}
137-
dateReviewed={changeRequest.dateReviewed}
138-
/>
139-
</Grid>
140-
<Grid item md={6}>
141-
<ImplementedChangesList
142-
changes={changeRequest.implementedChanges || []}
143-
overallDateImplemented={changeRequest.dateImplemented}
144-
/>
131+
<Grid item xs={isStandard ? 5 : 0}>
132+
{isStandard && (
133+
<ProposedSolutionsList
134+
proposedSolutions={(changeRequest as StandardChangeRequest).proposedSolutions}
135+
crReviewed={changeRequest.accepted}
136+
crId={changeRequest.crId}
137+
/>
138+
)}
145139
</Grid>
146140
</Grid>
147141
</Grid>

src/frontend/src/pages/ChangeRequestDetailPage/ImplementedChangesList.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ interface ImplementedChangesListProps {
1818

1919
const ImplementedChangesList: React.FC<ImplementedChangesListProps> = ({ changes, overallDateImplemented }) => {
2020
return (
21-
<InfoBlock title={`Implemented Changes${overallDateImplemented ? datePipe(overallDateImplemented) : 'N/A'}`}>
21+
<InfoBlock title={`Implemented Changes${overallDateImplemented ? ' — ' + datePipe(overallDateImplemented) : ''}`}>
2222
<List>
2323
{changes.length === 0 ? (
2424
<Typography>— — There are no implemented changes for this change request.</Typography>

0 commit comments

Comments
 (0)