roughed-in cards (#221)

This commit is contained in:
Michael Quigley 2024-10-09 15:31:15 -04:00
parent 6eb60fcd3d
commit 258980c1a1
No known key found for this signature in database
GPG Key ID: 9B60314A9DD20A62
8 changed files with 112 additions and 68 deletions

View File

@ -0,0 +1,14 @@
import LanIcon from "@mui/icons-material/Lan";
const AccessCard = (props) => {
return (
<div className={"card"}>
<h2>{props.access.frontendToken} [<LanIcon />]</h2>
<p>
{props.access.token} &rarr; {props.access.bindAddress}
</p>
</div>
);
}
export default AccessCard;

View File

@ -3,13 +3,34 @@ import Overview from "./Overview.jsx";
import ShareDetail from "./ShareDetail.jsx";
import {useEffect, useState} from "react";
import {AgentApi, ApiClient} from "./api/src/index.js";
import buildOverview from "./model/overview.js";
import NavBar from "./NavBar.jsx";
import {Box, Modal} from "@mui/material";
const AgentUi = (props) => {
const AgentUi = () => {
const [version, setVersion] = useState("");
const [shares, setShares] = useState([]);
const [accesses, setAccesses] = useState([]);
const [overview, setOverview] = useState(new Map());
const [newShare, setNewShare] = useState(false);
let api = new AgentApi(new ApiClient(window.location.protocol+'//'+window.location.host));
const openNewShare = () => {
setNewShare(true);
}
const closeNewShare = () => {
setNewShare(false);
}
const shareStyle = {
position: 'absolute',
top: '25%',
left: '50%',
transform: 'translate(-50%, -50%)',
width: 600,
bgcolor: 'background.paper',
boxShadow: 24,
p: 4,
};
useEffect(() => {
let mounted = true;
@ -27,6 +48,7 @@ const AgentUi = (props) => {
if(mounted) {
setShares(data.shares);
setAccesses(data.accesses);
setOverview(buildOverview(data));
}
});
}, 1000);
@ -39,7 +61,7 @@ const AgentUi = (props) => {
const router = createBrowserRouter([
{
path: "/",
element: <Overview version={version} shares={shares} accesses={accesses} />
element: <Overview version={version} overview={overview} />
},
{
path: "/share/:token",
@ -47,7 +69,20 @@ const AgentUi = (props) => {
}
]);
return <RouterProvider router={router} />
return (
<>
<NavBar version={version} shareClick={openNewShare} />
<RouterProvider router={router} />
<Modal
open={newShare}
onClose={closeNewShare}
>
<Box sx={{ ...shareStyle }}>
<h2>New Share</h2>
</Box>
</Modal>
</>
);
}
export default AgentUi;

View File

@ -1,7 +1,5 @@
import {AppBar, Button, IconButton, Toolbar, Typography} from "@mui/material";
import MenuIcon from "@mui/icons-material/Menu";
import {Link} from "react-router-dom";
import ListIcon from "@mui/icons-material/List";
import LanIcon from "@mui/icons-material/Lan";
import ShareIcon from "@mui/icons-material/Share";
@ -21,8 +19,7 @@ const NavBar = (props) => {
<Typography variant="p" component={"div"} sx={{flexGrow: 1}}>
zrok Agent { props.version !== "" ? " | " + props.version : ""}
</Typography>
<Button color="inherit" component={Link} to={"/"}><ListIcon /></Button>
<Button color="inherit"><LanIcon /></Button>
<Button color="inherit" onClick={props.shareClick}><LanIcon /></Button>
<Button color="inherit"><ShareIcon /></Button>
</Toolbar>
</AppBar>

View File

@ -1,68 +1,25 @@
import "bootstrap/dist/css/bootstrap.min.css";
import DataTable from "react-data-table-component";
import NavBar from "./NavBar.jsx";
import ShareCard from "./ShareCard.jsx";
import AccessCard from "./AccessCard.jsx";
const Overview = (props) => {
const shareColumns = [
{
name: 'Token',
selector: row => <a href={"/share/"+row.token}>{row.token}</a>
},
{
name: 'Share Mode',
selector: row => row.shareMode
},
{
name: 'Backend Mode',
selector: row => row.backendMode
},
{
name: 'Target',
selector: row => row.backendEndpoint,
},
{
name: 'Frontend Endpoints',
selector: row => <div>{row.shareMode === "public" ? row.frontendEndpoint.map((fe) => <a href={fe.toString()} target={"_"}>{fe}</a>) : "---"}</div>,
grow: 2
}
];
let cards = [];
props.overview.forEach((row) => {
switch(row.type) {
case "share":
cards.push(<ShareCard share={row.v} />);
break;
const accessColumns = [
{
name: 'Frontend Token',
selector: row => row.frontendToken
},
{
name: 'Token',
selector: row => row.token
},
{
name: 'Bind Address',
selector: row => row.bindAddress
},
];
case "access":
cards.push(<AccessCard access={row.v} />);
break;
}
});
return (
<>
<NavBar version={props.version} />
<div className={"info"}>
<h2>Shares</h2>
<DataTable
columns={shareColumns}
data={props.shares}
noDataComponent={<div/>}
/>
</div>
<div className={"info"}>
<h2>Accesses</h2>
<DataTable
columns={accessColumns}
data={props.accesses}
noDataComponent={<div/>}
/>
</div>
{cards}
</>
)
}

View File

@ -0,0 +1,20 @@
import ShareIcon from "@mui/icons-material/Share";
const ShareCard = (props) => {
let frontends = [];
props.share.frontendEndpoint.map((fe) => {
frontends.push(<a href={fe.toString()} target={"_"}>{fe}</a>);
})
return (
<div className={"card"}>
<h2>{props.share.token} [<ShareIcon />]</h2>
<p>({props.share.shareMode}, {props.share.backendMode})</p>
<p>
{props.share.backendEndpoint} &rarr; {frontends}
</p>
</div>
);
}
export default ShareCard;

View File

@ -1,4 +1,3 @@
import NavBar from "./NavBar.jsx";
import {useParams} from "react-router-dom";
const ShareDetail = (props) => {
@ -6,8 +5,6 @@ const ShareDetail = (props) => {
return (
<>
<NavBar version={props.version} />
<h1>Share {params.token}</h1>
</>
)

View File

@ -53,4 +53,10 @@ button:focus-visible {
.info {
margin-top: 5em;
}
.card {
margin-top: 2em;
padding: 1em;
border: 0;
}

View File

@ -0,0 +1,18 @@
const buildOverview = (status) => {
let overview = new Map();
status.accesses.map(acc => {
overview.set(acc.frontendToken, {
type: "access",
v: acc
});
});
status.shares.map(shr => {
overview.set(shr.token, {
type: "share",
v: shr
})
});
return overview;
}
export default buildOverview;