diff --git a/package.json b/package.json index 823f447..7e6edbe 100644 --- a/package.json +++ b/package.json @@ -31,6 +31,7 @@ "react": "^18.2.0", "react-cookie": "^5.0.0", "react-dom": "^18.2.0", + "react-error-boundary": "^4.0.11", "react-helmet": "^6.1.0", "react-router-dom": "^6.14.1", "react-simple-code-editor": "^0.13.1", diff --git a/src/App.tsx b/src/App.tsx index b22383a..af26dd9 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -13,8 +13,10 @@ import Nodes from "./pages/Nodes"; import Node from "./pages/Node"; import StatsNodesLock from "./pages/StatsNodesLock"; import StatsNodesJobs from "./pages/StatsNodesJobs"; +import { ErrorBoundary } from "react-error-boundary"; import "./App.css"; +import ErrorFallback from "./components/ErrorFallback"; type AppProps = { darkMode: boolean; @@ -37,19 +39,21 @@ function App(props: AppProps) {
- - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - + + + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + +
); diff --git a/src/components/CodeBlock/index.jsx b/src/components/CodeBlock/index.jsx new file mode 100644 index 0000000..9a3c0ba --- /dev/null +++ b/src/components/CodeBlock/index.jsx @@ -0,0 +1,34 @@ +import Editor from "react-simple-code-editor"; +import { highlight, languages } from "prismjs/components/prism-core"; +import 'prismjs/components/prism-clike'; +import "prismjs/components/prism-yaml"; +import 'prismjs/components/prism-javascript'; + +export default function CodeBlock(props) { + const language = languages[props.language]; + if ( ! props.value ) return null; + return ( + { + if (!! language ) return highlight(code, language); + return code; + }} + style={{ + fontFamily: [ + "ui-monospace", + "SFMono-Regular", + '"SF Mono"', + "Menlo", + "Consolas", + "Liberation Mono", + '"Lucida Console"', + "Courier", + "monospace", + ].join(","), + textAlign: "initial", + }} + /> + ) +} diff --git a/src/components/ErrorFallback/index.tsx b/src/components/ErrorFallback/index.tsx new file mode 100644 index 0000000..f5f5815 --- /dev/null +++ b/src/components/ErrorFallback/index.tsx @@ -0,0 +1,24 @@ +import Typography from "@mui/material/Typography"; +import Link from "../Link"; + +import CodeBlock from "../CodeBlock"; + +export default function ErrorFallback(props: {error: Error}) { + return ( +
+ + Apologies - the component encountered an error. Please  + + file an issue + +  including this error message: + + +
+ ); +} diff --git a/src/components/JobList/index.tsx b/src/components/JobList/index.tsx index 8fba7d1..ce40d37 100644 --- a/src/components/JobList/index.tsx +++ b/src/components/JobList/index.tsx @@ -202,7 +202,7 @@ type JobListProps = { export default function JobList({ query, sortMode }: JobListProps) { const options = useDefaultTableOptions(); - const data = query.data?.jobs || []; + const data = (query.data?.jobs || []).filter(item => item.id); const table = useMaterialReactTable({ ...options, columns, diff --git a/src/pages/Job/index.jsx b/src/pages/Job/index.jsx index 89997a0..cf06f74 100644 --- a/src/pages/Job/index.jsx +++ b/src/pages/Job/index.jsx @@ -13,14 +13,12 @@ import HighlightOffIcon from "@mui/icons-material/HighlightOff"; import FolderIcon from '@mui/icons-material/Folder'; import formatDuration from "date-fns/formatDuration"; import { isValid, parse } from "date-fns"; -import Editor from "react-simple-code-editor"; -import { highlight, languages } from "prismjs/components/prism-core"; -import "prismjs/components/prism-yaml"; import "prismjs/themes/prism-tomorrow.css"; import { Helmet } from "react-helmet"; import YAML from "json-to-pretty-yaml"; import Link from "../../components/Link"; +import CodeBlock from "../../components/CodeBlock"; import { useJob } from "../../lib/paddles"; import { getDuration, dirName } from "../../lib/utils"; @@ -150,25 +148,7 @@ function JobDetails({ query }) { if (query.isError) return "!!!"; const code = YAML.stringify(query.data); return ( - highlight(code, languages.yaml)} - style={{ - fontFamily: [ - "ui-monospace", - "SFMono-Regular", - '"SF Mono"', - "Menlo", - "Consolas", - "Liberation Mono", - '"Lucida Console"', - "Courier", - "monospace", - ].join(","), - textAlign: "initial", - }} - /> + ); }