Init diagnostics.
This commit is contained in:
parent
6d32d2d005
commit
4d2ba762f3
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
|
@ -20,6 +20,7 @@
|
||||||
"prettier": "^3.8.1",
|
"prettier": "^3.8.1",
|
||||||
"react": "^19.2.0",
|
"react": "^19.2.0",
|
||||||
"react-bootstrap": "^2.10.10",
|
"react-bootstrap": "^2.10.10",
|
||||||
|
"react-bootstrap-icons": "^1.11.6",
|
||||||
"react-dom": "^19.2.0",
|
"react-dom": "^19.2.0",
|
||||||
"react-router-dom": "^7.13.1",
|
"react-router-dom": "^7.13.1",
|
||||||
"yaml": "^2.8.2"
|
"yaml": "^2.8.2"
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ import { Provider as JotaiProvider } from "jotai";
|
||||||
import { Home } from "./Home.tsx";
|
import { Home } from "./Home.tsx";
|
||||||
import { Autonomy } from "./Autonomy.tsx";
|
import { Autonomy } from "./Autonomy.tsx";
|
||||||
import { Version } from "./Version.tsx";
|
import { Version } from "./Version.tsx";
|
||||||
|
import { Diagnostics } from "./Diagnostics.tsx";
|
||||||
import "./App.css";
|
import "./App.css";
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
|
|
@ -43,6 +44,10 @@ const router = createBrowserRouter([
|
||||||
path: "/autonomy",
|
path: "/autonomy",
|
||||||
element: <Autonomy />,
|
element: <Autonomy />,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: "/diagnostics",
|
||||||
|
element: <Diagnostics />,
|
||||||
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
export default App;
|
export default App;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,70 @@
|
||||||
|
//
|
||||||
|
// Copyright 2026 James Pace
|
||||||
|
//
|
||||||
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
|
//
|
||||||
|
// This Source Code Form is "Incompatible With Secondary Licenses", as
|
||||||
|
// defined by the Mozilla Public License, v. 2.0.
|
||||||
|
//
|
||||||
|
import { AppNav, Footer } from "./components/AppNav.tsx";
|
||||||
|
import { TreeView } from "./components/DiagnosticView.tsx";
|
||||||
|
import { Container, Row, Col, Card } from "react-bootstrap";
|
||||||
|
import { atom, useAtomValue } from "jotai";
|
||||||
|
import { atomWithQuery } from "jotai-tanstack-query";
|
||||||
|
|
||||||
|
const diagQueryFn = async () => {
|
||||||
|
const resp = await fetch("api/diagnostics");
|
||||||
|
if (!resp.ok) {
|
||||||
|
throw new Error("Network response was not ok");
|
||||||
|
}
|
||||||
|
return resp.json();
|
||||||
|
};
|
||||||
|
|
||||||
|
const diagQueryAtom = atomWithQuery(() => ({
|
||||||
|
queryKey: ["diagnostics"],
|
||||||
|
queryFn: diagQueryFn,
|
||||||
|
}));
|
||||||
|
|
||||||
|
const diagAtom = atom((get) => {
|
||||||
|
const diag = get(diagQueryAtom);
|
||||||
|
if (diag.isPending) {
|
||||||
|
return "Loading...";
|
||||||
|
}
|
||||||
|
if (diag.isError) {
|
||||||
|
return "Error loading!";
|
||||||
|
}
|
||||||
|
if (!diag.data.status) {
|
||||||
|
return "Failed to get diagnostic information.";
|
||||||
|
}
|
||||||
|
return diag.data.message
|
||||||
|
});
|
||||||
|
|
||||||
|
export function Diagnostics() {
|
||||||
|
const diagnostics = useAtomValue(diagAtom);
|
||||||
|
|
||||||
|
const diagContent = () => {
|
||||||
|
if (typeof diagnostics === 'string' || diagnostics instanceof String)
|
||||||
|
{
|
||||||
|
return (<pre> {diagnostics} </pre>);
|
||||||
|
}
|
||||||
|
return (<TreeView data={diagnostics}/>);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<AppNav />
|
||||||
|
<Container className="vert-padded">
|
||||||
|
<Card className="padded">
|
||||||
|
<Card.Title>Diagnostics</Card.Title>
|
||||||
|
<Card.Body>
|
||||||
|
{diagContent()}
|
||||||
|
</Card.Body>
|
||||||
|
</Card>
|
||||||
|
</Container>
|
||||||
|
<Footer />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -30,6 +30,9 @@ export function AppNav() {
|
||||||
<Nav.Link as={Link} to="/autonomy">
|
<Nav.Link as={Link} to="/autonomy">
|
||||||
Autonomy
|
Autonomy
|
||||||
</Nav.Link>
|
</Nav.Link>
|
||||||
|
<Nav.Link as={Link} to="/diagnostics">
|
||||||
|
Diagnostics
|
||||||
|
</Nav.Link>
|
||||||
</Nav>
|
</Nav>
|
||||||
</Navbar.Collapse>
|
</Navbar.Collapse>
|
||||||
</Container>
|
</Container>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,71 @@
|
||||||
|
import React, { useState } from 'react';
|
||||||
|
import { ListGroup, Collapse } from 'react-bootstrap';
|
||||||
|
|
||||||
|
/*
|
||||||
|
const treeData = [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
label: "Documents",
|
||||||
|
children: [
|
||||||
|
{ id: 2, label: "Resume.pdf" },
|
||||||
|
{ id: 3, label: "CoverLetter.pdf" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 4,
|
||||||
|
label: "Pictures",
|
||||||
|
children: [
|
||||||
|
{ id: 5, label: "Vacation.jpg" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
];
|
||||||
|
*/
|
||||||
|
|
||||||
|
export function TreeView({ data })
|
||||||
|
{
|
||||||
|
return (
|
||||||
|
<ListGroup className="border-0">
|
||||||
|
{data.children.map(node => (
|
||||||
|
<TreeNode key={node.id} node={node} />
|
||||||
|
))}
|
||||||
|
</ListGroup>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
function SingleNode({ node }) {
|
||||||
|
console.log(node);
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
{node.name} {node.level}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function TreeNode({ node }) {
|
||||||
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
|
const hasChildren = node.children && node.children.length > 0;
|
||||||
|
const onClick = () => {
|
||||||
|
if(hasChildren) {
|
||||||
|
setIsOpen(!isOpen);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ListGroup.Item className="border-0 ps-3 py-1">
|
||||||
|
<div onClick={onClick}>
|
||||||
|
<SingleNode node={node.status} />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Collapse in={isOpen}>
|
||||||
|
<div>
|
||||||
|
<ListGroup className="ms-2 border-start">
|
||||||
|
{node.children.map(child => (
|
||||||
|
<TreeNode key={child.id} node={child} />
|
||||||
|
))}
|
||||||
|
</ListGroup>
|
||||||
|
</div>
|
||||||
|
</Collapse>
|
||||||
|
</ListGroup.Item>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
14
yarn.lock
14
yarn.lock
|
|
@ -1192,6 +1192,7 @@ __metadata:
|
||||||
prettier: "npm:^3.8.1"
|
prettier: "npm:^3.8.1"
|
||||||
react: "npm:^19.2.0"
|
react: "npm:^19.2.0"
|
||||||
react-bootstrap: "npm:^2.10.10"
|
react-bootstrap: "npm:^2.10.10"
|
||||||
|
react-bootstrap-icons: "npm:^1.11.6"
|
||||||
react-dom: "npm:^19.2.0"
|
react-dom: "npm:^19.2.0"
|
||||||
react-router-dom: "npm:^7.13.1"
|
react-router-dom: "npm:^7.13.1"
|
||||||
typescript: "npm:~5.9.3"
|
typescript: "npm:~5.9.3"
|
||||||
|
|
@ -2484,7 +2485,7 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"prop-types@npm:^15.6.2, prop-types@npm:^15.8.1":
|
"prop-types@npm:^15.6.2, prop-types@npm:^15.7.2, prop-types@npm:^15.8.1":
|
||||||
version: 15.8.1
|
version: 15.8.1
|
||||||
resolution: "prop-types@npm:15.8.1"
|
resolution: "prop-types@npm:15.8.1"
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|
@ -2502,6 +2503,17 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"react-bootstrap-icons@npm:^1.11.6":
|
||||||
|
version: 1.11.6
|
||||||
|
resolution: "react-bootstrap-icons@npm:1.11.6"
|
||||||
|
dependencies:
|
||||||
|
prop-types: "npm:^15.7.2"
|
||||||
|
peerDependencies:
|
||||||
|
react: ">=16.8.6"
|
||||||
|
checksum: 10c0/4dfd75c980a4431032e7d861d52efeb18cb141e00300ae1cf055dcfcb1fd7689991d8b467c38f1103563662bbbd61aaf247093e7c04f6f1ad0aae86feff5047d
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"react-bootstrap@npm:^2.10.10":
|
"react-bootstrap@npm:^2.10.10":
|
||||||
version: 2.10.10
|
version: 2.10.10
|
||||||
resolution: "react-bootstrap@npm:2.10.10"
|
resolution: "react-bootstrap@npm:2.10.10"
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue