mirror of
https://github.com/openziti/zrok.git
synced 2024-12-22 14:50:55 +01:00
new share modal ported to typescript (#221)
This commit is contained in:
parent
0f2418e921
commit
79449859de
75
agent/agentUiTs/package-lock.json
generated
75
agent/agentUiTs/package-lock.json
generated
@ -12,6 +12,7 @@
|
||||
"@emotion/styled": "^11.13.0",
|
||||
"@mui/icons-material": "^6.1.7",
|
||||
"@mui/material": "^6.1.7",
|
||||
"formik": "^2.4.6",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1"
|
||||
},
|
||||
@ -1703,6 +1704,16 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/hoist-non-react-statics": {
|
||||
"version": "3.3.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.5.tgz",
|
||||
"integrity": "sha512-SbcrWzkKBw2cdwRTwQAswfpB9g9LJWfjtUeW/jvNwbhC8cpmmNYVePa+ncbUe0rGTQ7G3Ff6mYUN2VMfLVr+Sg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/react": "*",
|
||||
"hoist-non-react-statics": "^3.3.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/json-schema": {
|
||||
"version": "7.0.15",
|
||||
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
|
||||
@ -2301,6 +2312,15 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/deepmerge": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-2.2.1.tgz",
|
||||
"integrity": "sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/dom-helpers": {
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz",
|
||||
@ -2696,6 +2716,31 @@
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/formik": {
|
||||
"version": "2.4.6",
|
||||
"resolved": "https://registry.npmjs.org/formik/-/formik-2.4.6.tgz",
|
||||
"integrity": "sha512-A+2EI7U7aG296q2TLGvNapDNTZp1khVt5Vk0Q/fyfSROss0V/V6+txt2aJnwEos44IxTCW/LYAi/zgWzlevj+g==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
"url": "https://opencollective.com/formik"
|
||||
}
|
||||
],
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@types/hoist-non-react-statics": "^3.3.1",
|
||||
"deepmerge": "^2.1.1",
|
||||
"hoist-non-react-statics": "^3.3.0",
|
||||
"lodash": "^4.17.21",
|
||||
"lodash-es": "^4.17.21",
|
||||
"react-fast-compare": "^2.0.1",
|
||||
"tiny-warning": "^1.0.2",
|
||||
"tslib": "^2.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/fsevents": {
|
||||
"version": "2.3.3",
|
||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
|
||||
@ -3014,6 +3059,18 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/lodash": {
|
||||
"version": "4.17.21",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
||||
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/lodash-es": {
|
||||
"version": "4.17.21",
|
||||
"resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz",
|
||||
"integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/lodash.merge": {
|
||||
"version": "4.6.2",
|
||||
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
|
||||
@ -3374,6 +3431,12 @@
|
||||
"react": "^18.3.1"
|
||||
}
|
||||
},
|
||||
"node_modules/react-fast-compare": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-2.0.4.tgz",
|
||||
"integrity": "sha512-suNP+J1VU1MWFKcyt7RtjiSWUjvidmQSlqu+eHslq+342xCbGTYmC0mEhPCOHxlW0CywylOC1u2DFAT+bv4dBw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/react-is": {
|
||||
"version": "18.3.1",
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz",
|
||||
@ -3616,6 +3679,12 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/tiny-warning": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz",
|
||||
"integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/to-regex-range": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
||||
@ -3642,6 +3711,12 @@
|
||||
"typescript": ">=4.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/tslib": {
|
||||
"version": "2.8.1",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
|
||||
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
|
||||
"license": "0BSD"
|
||||
},
|
||||
"node_modules/type-check": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
|
||||
|
@ -14,6 +14,7 @@
|
||||
"@emotion/styled": "^11.13.0",
|
||||
"@mui/icons-material": "^6.1.7",
|
||||
"@mui/material": "^6.1.7",
|
||||
"formik": "^2.4.6",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1"
|
||||
},
|
||||
|
@ -3,6 +3,7 @@ import {AppBar, Box, Button, Card, Chip, Grid2, Toolbar, Typography} from "@mui/
|
||||
import LanIcon from "@mui/icons-material/Lan";
|
||||
import {AccessDetail} from "./api";
|
||||
import DeleteIcon from "@mui/icons-material/Delete";
|
||||
import {GetAgentApi} from "./model/api.ts";
|
||||
|
||||
interface AccessCardProps {
|
||||
accessObject: AgentObject;
|
||||
@ -10,6 +11,14 @@ interface AccessCardProps {
|
||||
|
||||
function AccessCard({ accessObject }: AccessCardProps) {
|
||||
let access = (accessObject.v as AccessDetail);
|
||||
|
||||
const releaseAccess = () => {
|
||||
GetAgentApi().agentReleaseAccess({frontendToken: access.frontendToken})
|
||||
.catch(e => {
|
||||
console.log(e);
|
||||
});
|
||||
}
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<AppBar position="sticky">
|
||||
@ -34,7 +43,7 @@ function AccessCard({ accessObject }: AccessCardProps) {
|
||||
</Box>
|
||||
<Grid2 container sx={{ flexGrow: 1 }}>
|
||||
<Grid2 display="flex" justifyContent="right" size="grow">
|
||||
<Button variant="contained"><DeleteIcon /></Button>
|
||||
<Button variant="contained" onClick={releaseAccess}><DeleteIcon /></Button>
|
||||
</Grid2>
|
||||
</Grid2>
|
||||
</Card>
|
||||
|
@ -3,10 +3,19 @@ import {GetAgentApi} from "./model/api.ts";
|
||||
import NavBar from "./NavBar.tsx";
|
||||
import {AgentObject, buildOverview} from "./model/overview.ts";
|
||||
import Overview from "./Overview.tsx";
|
||||
import NewShareModal from "./NewShareModal.tsx";
|
||||
|
||||
const AgentUi = () => {
|
||||
const [version, setVersion] = useState("unset");
|
||||
const [overview, setOverview] = useState(new Array<AgentObject>());
|
||||
const [newShareOpen, setNewShareOpen] = useState(false);
|
||||
|
||||
const openNewShare = () => {
|
||||
setNewShareOpen(true);
|
||||
}
|
||||
const closeNewShare = () => {
|
||||
setNewShareOpen(false);
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
GetAgentApi().agentVersion()
|
||||
@ -40,8 +49,9 @@ const AgentUi = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<NavBar version={version} />
|
||||
<NavBar version={version} shareClick={openNewShare} />
|
||||
<Overview overview={overview} />
|
||||
<NewShareModal isOpen={newShareOpen} close={closeNewShare} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
@ -5,9 +5,10 @@ import ShareIcon from "@mui/icons-material/Share";
|
||||
|
||||
interface NavBarProps {
|
||||
version: string;
|
||||
shareClick: () => void;
|
||||
}
|
||||
|
||||
function NavBar({ version }: NavBarProps) {
|
||||
function NavBar({ version, shareClick }: NavBarProps) {
|
||||
return (
|
||||
<Box ssx={{ flexGrow: 1 }}>
|
||||
<AppBar position="static">
|
||||
@ -20,7 +21,7 @@ function NavBar({ version }: NavBarProps) {
|
||||
</Typography>
|
||||
<Grid2 container sx={{ flexGrow: 1 }}>
|
||||
<Grid2 display="flex" justifyContent="right" size="grow">
|
||||
<Button color="inherit"><ShareIcon /></Button>
|
||||
<Button color="inherit" onClick={shareClick}><ShareIcon /></Button>
|
||||
</Grid2>
|
||||
<Grid2 display="flex" justifyContent="right">
|
||||
<Button color="inherit" ><LanIcon /></Button>
|
||||
|
145
agent/agentUiTs/src/NewShareModal.tsx
Normal file
145
agent/agentUiTs/src/NewShareModal.tsx
Normal file
@ -0,0 +1,145 @@
|
||||
import {useFormik} from "formik";
|
||||
import {GetAgentApi} from "./model/api.ts";
|
||||
import {useState} from "react";
|
||||
import {Box, Button, Checkbox, FormControlLabel, MenuItem, Modal, TextField} from "@mui/material";
|
||||
import {modalStyle} from "./model/theme.ts";
|
||||
|
||||
interface NewShareModalProps {
|
||||
close: () => void;
|
||||
isOpen: boolean;
|
||||
}
|
||||
|
||||
function NewShareModal({ close, isOpen }: NewShareModalProps) {
|
||||
const [errorMessage, setErrorMessage] = useState(<></>);
|
||||
|
||||
const form = useFormik({
|
||||
initialValues: {
|
||||
shareMode: "public",
|
||||
backendMode: "proxy",
|
||||
target: "",
|
||||
insecure: false,
|
||||
},
|
||||
onSubmit: v => {
|
||||
setErrorMessage(<></>);
|
||||
switch(v.shareMode) {
|
||||
case "public":
|
||||
GetAgentApi().agentSharePublic(v)
|
||||
.then(r => {
|
||||
close();
|
||||
})
|
||||
.catch(e => {
|
||||
e.response().json().then(ex => {
|
||||
setErrorMessage(<p>{ex.message}</p>);
|
||||
console.log(ex.message);
|
||||
})
|
||||
});
|
||||
break;
|
||||
|
||||
case "private":
|
||||
GetAgentApi().agentSharePrivate(v)
|
||||
.then(r => {
|
||||
close();
|
||||
})
|
||||
.catch(e => {
|
||||
e.response().json().then(ex => {
|
||||
setErrorMessage(<p>{ex.message}</p>);
|
||||
console.log(ex.message);
|
||||
})
|
||||
});
|
||||
break;
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
return (
|
||||
<Modal open={isOpen} onClose={close}>
|
||||
<Box sx={{ ...modalStyle }}>
|
||||
<h2>Share...</h2>
|
||||
{errorMessage}
|
||||
<form onSubmit={form.handleSubmit}>
|
||||
<TextField
|
||||
fullWidth
|
||||
select
|
||||
id="shareMode"
|
||||
name="shareMode"
|
||||
label="Share Mode"
|
||||
value={form.values.shareMode}
|
||||
onChange={form.handleChange}
|
||||
onBlur={form.handleBlur}
|
||||
sx={{ mt: 2 }}
|
||||
>
|
||||
<MenuItem value="public">public</MenuItem>
|
||||
<MenuItem value="private">private</MenuItem>
|
||||
</TextField>
|
||||
{form.values.shareMode === "public" && (
|
||||
<TextField
|
||||
fullWidth select
|
||||
id="backendMode"
|
||||
name="backendMode"
|
||||
label="Backend Mode"
|
||||
value={form.values.backendMode}
|
||||
onChange={form.handleChange}
|
||||
onBlur={form.handleBlur}
|
||||
sx={{ mt: 2 }}
|
||||
>
|
||||
<MenuItem value="proxy">proxy</MenuItem>
|
||||
<MenuItem value="web">web</MenuItem>
|
||||
<MenuItem value="caddy">caddy</MenuItem>
|
||||
<MenuItem value="drive">drive</MenuItem>
|
||||
</TextField>
|
||||
)}
|
||||
{form.values.shareMode === "private" && (
|
||||
<TextField
|
||||
fullWidth select
|
||||
id="backendMode"
|
||||
name="backendMode"
|
||||
label="Backend Mode"
|
||||
value={form.values.backendMode}
|
||||
onChange={form.handleChange}
|
||||
onBlur={form.handleBlur}
|
||||
sx={{ mt: 2 }}
|
||||
>
|
||||
<MenuItem value="proxy">proxy</MenuItem>
|
||||
<MenuItem value="web">web</MenuItem>
|
||||
<MenuItem value="tcpTunnel">tcpTunnel</MenuItem>
|
||||
<MenuItem value="udpTunnel">udpTunnel</MenuItem>
|
||||
<MenuItem value="caddy">caddy</MenuItem>
|
||||
<MenuItem value="drive">drive</MenuItem>
|
||||
<MenuItem value="socks">socks</MenuItem>
|
||||
<MenuItem value="vpn">vpn</MenuItem>
|
||||
</TextField>
|
||||
)}
|
||||
<TextField
|
||||
fullWidth
|
||||
id="target"
|
||||
name="target"
|
||||
label="Target"
|
||||
value={form.values.target}
|
||||
onChange={form.handleChange}
|
||||
onBlur={form.handleBlur}
|
||||
sx={{ mt: 2 }}
|
||||
/>
|
||||
{form.values.backendMode === "proxy" && (
|
||||
<Box>
|
||||
<FormControlLabel
|
||||
control={<Checkbox
|
||||
id="insecure"
|
||||
name="insecure"
|
||||
label="Insecure"
|
||||
checked={form.values.insecure}
|
||||
onChange={form.handleChange}
|
||||
onBlur={form.handleBlur}
|
||||
/>}
|
||||
label="Insecure"
|
||||
sx={{ mt: 2 }}
|
||||
/>
|
||||
</Box>
|
||||
)}
|
||||
<Button color="primary" variant="contained" type="submit" sx={{ mt: 2 }}>Create Share</Button>
|
||||
</form>
|
||||
</Box>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
|
||||
export default NewShareModal;
|
@ -4,6 +4,7 @@ import {ShareDetail} from "./api";
|
||||
import {AppBar, Box, Button, Card, Chip, Grid2, Toolbar, Typography} from "@mui/material";
|
||||
import ShareIcon from "@mui/icons-material/Share";
|
||||
import DeleteIcon from "@mui/icons-material/Delete";
|
||||
import {GetAgentApi} from "./model/api.ts";
|
||||
|
||||
interface ShareCardProps {
|
||||
shareObject: AgentObject;
|
||||
@ -16,6 +17,13 @@ function ShareCard({ shareObject }: ShareCardProps) {
|
||||
frontends.push(<a key={share.token} href={fe} target="_">{fe}</a>);
|
||||
});
|
||||
|
||||
const releaseShare = () => {
|
||||
GetAgentApi().agentReleaseShare({token: share.token})
|
||||
.catch(e => {
|
||||
console.log(e);
|
||||
});
|
||||
}
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<AppBar position="sticky">
|
||||
@ -46,7 +54,7 @@ function ShareCard({ shareObject }: ShareCardProps) {
|
||||
</Box>
|
||||
<Grid2 container sx={{ flexGrow: 1 }}>
|
||||
<Grid2 display="flex" justifyContent="right" size="grow">
|
||||
<Button variant="contained"><DeleteIcon /></Button>
|
||||
<Button variant="contained" onClick={releaseShare}><DeleteIcon /></Button>
|
||||
</Grid2>
|
||||
</Grid2>
|
||||
</Card>
|
||||
|
Loading…
Reference in New Issue
Block a user