|
1 | 1 | import AlertTitle from "@mui/material/AlertTitle"; |
2 | | -import { getErrorDetail, getErrorMessage } from "api/errors"; |
| 2 | +import { getErrorDetail, getErrorMessage, getErrorStatus } from "api/errors"; |
3 | 3 | import type { FC } from "react"; |
| 4 | +import { Link } from "../Link/Link"; |
4 | 5 | import { Alert, AlertDetail, type AlertProps } from "./Alert"; |
5 | 6 |
|
6 | 7 | export const ErrorAlert: FC< |
7 | 8 | Omit<AlertProps, "severity" | "children"> & { error: unknown } |
8 | 9 | > = ({ error, ...alertProps }) => { |
9 | 10 | const message = getErrorMessage(error, "Something went wrong."); |
10 | 11 | const detail = getErrorDetail(error); |
| 12 | + const status = getErrorStatus(error); |
11 | 13 |
|
12 | 14 | // For some reason, the message and detail can be the same on the BE, but does |
13 | 15 | // not make sense in the FE to showing them duplicated |
14 | 16 | const shouldDisplayDetail = message !== detail; |
15 | 17 |
|
16 | 18 | return ( |
17 | 19 | <Alert severity="error" {...alertProps}> |
18 | | - {detail ? ( |
19 | | - <> |
20 | | - <AlertTitle>{message}</AlertTitle> |
21 | | - {shouldDisplayDetail && <AlertDetail>{detail}</AlertDetail>} |
22 | | - </> |
23 | | - ) : ( |
24 | | - message |
25 | | - )} |
| 20 | + { |
| 21 | + // When the error is a Forbidden response we include a link for the user to |
| 22 | + // go back to a known viewable page. |
| 23 | + status === 403 ? ( |
| 24 | + <> |
| 25 | + <AlertTitle>{message}</AlertTitle> |
| 26 | + <AlertDetail> |
| 27 | + {detail}{" "} |
| 28 | + <Link href="/workspaces" className="w-fit"> |
| 29 | + Go to workspaces |
| 30 | + </Link> |
| 31 | + </AlertDetail> |
| 32 | + </> |
| 33 | + ) : detail ? ( |
| 34 | + <> |
| 35 | + <AlertTitle>{message}</AlertTitle> |
| 36 | + {shouldDisplayDetail && <AlertDetail>{detail}</AlertDetail>} |
| 37 | + </> |
| 38 | + ) : ( |
| 39 | + message |
| 40 | + ) |
| 41 | + } |
26 | 42 | </Alert> |
27 | 43 | ); |
28 | 44 | }; |
0 commit comments