Skip to content

Commit

Permalink
feat: submissions feed reflects events rather than successful audit e…
Browse files Browse the repository at this point in the history
…ntries (#3153)

Co-authored-by: Ian Jones <[email protected]>
  • Loading branch information
jessicamcinchak and ianjon3s authored May 17, 2024
1 parent ce6e37e commit 59c9f50
Show file tree
Hide file tree
Showing 18 changed files with 414 additions and 814 deletions.
4 changes: 3 additions & 1 deletion api.planx.uk/modules/send/email/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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",
});
});
});
Expand Down
4 changes: 3 additions & 1 deletion api.planx.uk/modules/send/email/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,9 @@ export async function sendToEmail(
);

return res.status(200).send({
message: `Successfully sent "Submit" email`,
message: `Successfully sent to email`,
inbox: sendToEmail,
govuk_notify_template: "Submit",
});
} catch (error) {
return next({
Expand Down
2 changes: 1 addition & 1 deletion api.planx.uk/modules/send/s3/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export async function sendToS3(
if (!powerAutomateWebhookURL || !powerAutomateAPIKey) {
return next({
status: 400,
message: `Send to S3 is not enabled for this local authority (${localAuthority})`,
message: `Upload to S3 is not enabled for this local authority (${localAuthority})`,
});
}

Expand Down
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",
}));

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>
</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.

Loading

0 comments on commit 59c9f50

Please sign in to comment.