-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: submissions feed reflects events rather than successful audit entries only #3153
Changes from all commits
1812cbd
e445ca4
f528c5e
da25484
2c931d7
b925a59
10236d2
d083489
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -118,7 +118,9 @@ describe(`sending an application by email to a planning office`, () => { | |
.expect(200) | ||
.then((res) => { | ||
expect(res.body).toEqual({ | ||
message: 'Successfully sent "Submit" email', | ||
message: `Successfully sent to email`, | ||
inbox: "[email protected]", | ||
govuk_notify_template: "Submit", | ||
}); | ||
}); | ||
}); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,185 @@ | ||
import KeyboardArrowDown from "@mui/icons-material/KeyboardArrowDown"; | ||
import KeyboardArrowUp from "@mui/icons-material/KeyboardArrowUp"; | ||
import Payment from "@mui/icons-material/Payment"; | ||
import Send from "@mui/icons-material/Send"; | ||
import Box from "@mui/material/Box"; | ||
import Chip from "@mui/material/Chip"; | ||
import Collapse from "@mui/material/Collapse"; | ||
import IconButton from "@mui/material/IconButton"; | ||
import { styled } from "@mui/material/styles"; | ||
import Table from "@mui/material/Table"; | ||
import TableBody from "@mui/material/TableBody"; | ||
import TableCell from "@mui/material/TableCell"; | ||
import TableContainer from "@mui/material/TableContainer"; | ||
import TableHead from "@mui/material/TableHead"; | ||
import TableRow from "@mui/material/TableRow"; | ||
import Typography from "@mui/material/Typography"; | ||
import DelayedLoadingIndicator from "components/DelayedLoadingIndicator"; | ||
import ErrorFallback from "components/ErrorFallback"; | ||
import { format } from "date-fns"; | ||
import React, { useState } from "react"; | ||
|
||
import { GetSubmissionsResponse, Submission } from "."; | ||
|
||
const ErrorSummary = styled(Box)(({ theme }) => ({ | ||
marginTop: theme.spacing(1), | ||
padding: theme.spacing(3), | ||
border: `5px solid ${theme.palette.error.main}`, | ||
})); | ||
|
||
const Response = styled(Box)(() => ({ | ||
fontSize: "1em", | ||
margin: 1, | ||
maxWidth: "contentWrap", | ||
overflowWrap: "break-word", | ||
whiteSpace: "pre-wrap", | ||
})); | ||
|
||
// Style the table container like an event feed with bottom-anchored scroll | ||
const Feed = styled(TableContainer)(() => ({ | ||
maxHeight: "60vh", | ||
overflow: "auto", | ||
display: "flex", | ||
flexDirection: "column-reverse", | ||
readingOrder: "flex-visual", | ||
})); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This post was helpful for figuring out the "feed" style, and has some good accessibility notes to revisit one day when we're ready to get the Editor certified https://kittygiraudel.com/2024/02/26/css-only-bottom-anchored-scrolling-area/ |
||
|
||
const EventsLog: React.FC<GetSubmissionsResponse> = ({ | ||
submissions, | ||
loading, | ||
error, | ||
}) => { | ||
if (loading) | ||
return ( | ||
<DelayedLoadingIndicator | ||
msDelayBeforeVisible={0} | ||
text="Fetching events..." | ||
/> | ||
); | ||
if (error) return <ErrorFallback error={error} />; | ||
if (submissions.length === 0) | ||
return ( | ||
<ErrorSummary role="status" data-testid="error-summary"> | ||
<Typography variant="h4" gutterBottom> | ||
{`No payments or submissions found for this service`} | ||
</Typography> | ||
<Typography variant="body2"> | ||
{`If you're looking for events before January 1, 2024, please contact a PlanX developer.`} | ||
</Typography> | ||
</ErrorSummary> | ||
); | ||
|
||
return ( | ||
<Feed> | ||
<Table stickyHeader sx={{ tableLayout: "fixed" }}> | ||
<TableHead> | ||
<TableRow sx={{ "& > *": { borderBottomColor: "black !important" } }}> | ||
<TableCell sx={{ width: 250 }}> | ||
<strong>Event</strong> | ||
</TableCell> | ||
<TableCell sx={{ width: 130 }}> | ||
<strong>Status</strong> | ||
</TableCell> | ||
<TableCell sx={{ width: 120 }}> | ||
<strong>Date</strong> | ||
</TableCell> | ||
<TableCell sx={{ width: 350 }}> | ||
<strong>Session ID</strong> | ||
</TableCell> | ||
<TableCell sx={{ width: 60 }}></TableCell> | ||
</TableRow> | ||
</TableHead> | ||
<TableBody> | ||
{submissions.map((submission, i) => ( | ||
<CollapsibleRow {...submission} key={i} /> | ||
))} | ||
</TableBody> | ||
</Table> | ||
</Feed> | ||
); | ||
}; | ||
|
||
const CollapsibleRow: React.FC<Submission> = (submission) => { | ||
const [open, setOpen] = useState<boolean>(false); | ||
|
||
return ( | ||
<React.Fragment key={`${submission.eventId}-${submission.createdAt}`}> | ||
<TableRow sx={{ "& > *": { borderBottom: "unset" } }}> | ||
<TableCell> | ||
<Box | ||
sx={{ | ||
display: "flex", | ||
flexDirection: "row", | ||
alignItems: "center", | ||
}} | ||
> | ||
{submission.eventType === "Pay" ? <Payment /> : <Send />} | ||
<Typography variant="body2" ml={1}> | ||
{submission.eventType} {submission.retry && ` [Retry]`} | ||
</Typography> | ||
</Box> | ||
</TableCell> | ||
<TableCell> | ||
{submission.status === "Success" ? ( | ||
<Chip label="Success" size="small" color="success" /> | ||
) : ( | ||
<Chip label={submission.status} size="small" color="error" /> | ||
)} | ||
</TableCell> | ||
<TableCell> | ||
{format(new Date(submission.createdAt), "dd/MM/yy hh:mm:ss")} | ||
</TableCell> | ||
<TableCell>{submission.sessionId}</TableCell> | ||
<TableCell> | ||
<IconButton | ||
aria-label="expand row" | ||
size="small" | ||
onClick={() => setOpen(!open)} | ||
> | ||
{open ? <KeyboardArrowUp /> : <KeyboardArrowDown />} | ||
</IconButton> | ||
jessicamcinchak marked this conversation as resolved.
Show resolved
Hide resolved
|
||
</TableCell> | ||
</TableRow> | ||
<TableRow sx={{ background: (theme) => theme.palette.background.paper }}> | ||
<TableCell sx={{ padding: 0, border: "none" }} colSpan={5}> | ||
<Collapse | ||
in={open} | ||
timeout="auto" | ||
unmountOnExit | ||
sx={{ | ||
borderBottom: (theme) => | ||
`1px solid ${theme.palette.border.light}`, | ||
padding: (theme) => theme.spacing(0, 1.5), | ||
}} | ||
> | ||
<FormattedResponse {...submission} /> | ||
</Collapse> | ||
</TableCell> | ||
</TableRow> | ||
</React.Fragment> | ||
); | ||
}; | ||
|
||
const FormattedResponse: React.FC<Submission> = (submission) => { | ||
if (submission.eventType === "Pay") { | ||
return ( | ||
<Response component="pre"> | ||
{JSON.stringify(submission.response, null, 2)} | ||
</Response> | ||
); | ||
} else { | ||
return ( | ||
<Response component="pre"> | ||
{submission.status === "Success" | ||
? JSON.stringify(JSON.parse(submission.response?.data?.body), null, 2) | ||
: JSON.stringify( | ||
JSON.parse(submission.response?.data?.message), | ||
null, | ||
2, | ||
)} | ||
</Response> | ||
); | ||
} | ||
}; | ||
|
||
export default EventsLog; |
This file was deleted.
This file was deleted.
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Slightly tweaking API responses here so they offer a bit more context in the "response" row (will apply to future events only) ✔️