Skip to content

Commit

Permalink
release access; better graph state merging (#724)
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelquigley committed Jan 22, 2025
1 parent 4551899 commit 6981e81
Show file tree
Hide file tree
Showing 2 changed files with 111 additions and 24 deletions.
117 changes: 97 additions & 20 deletions ui100/src/AccessPanel.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,58 @@
import {Node} from "@xyflow/react";
import {Button, Grid2, Tooltip, Typography} from "@mui/material";
import {Box, Button, Checkbox, FormControlLabel, Grid2, Modal, Tooltip, Typography} from "@mui/material";
import AccessIcon from "@mui/icons-material/Lan";
import useStore from "./model/store.ts";
import {useEffect, useState} from "react";
import {Configuration, Frontend, MetadataApi} from "./api";
import {useEffect, useRef, useState} from "react";
import {Configuration, Frontend, MetadataApi, ShareApi} from "./api";
import DeleteIcon from "@mui/icons-material/Delete";
import PropertyTable from "./PropertyTable.tsx";
import {modalStyle} from "./styling/theme.ts";

interface ReleaseAccessProps {
close: () => void;
isOpen: boolean;
detail: Frontend;
action: () => void;
}

const ReleaseAccessModal = ({ close, isOpen, detail, action }: ReleaseAccessProps) => {
const [feToken, setFeToken] = useState<String>("");
const [checked, setChecked] = useState<boolean>(false);
const checkedRef = useRef<boolean>(checked);

const toggleChecked = (event: React.ChangeEvent<HTMLInputElement>) => {
setChecked(!checkedRef.current);
}

useEffect(() => {
setChecked(false);
}, [isOpen]);

useEffect(() => {
if(detail && detail.token) {
setFeToken(detail.token);
}
}, [detail]);

return (
<Modal open={isOpen} onClose={close}>
<Box sx={{ ...modalStyle }}>
<Grid2 container sx={{ flexGrow: 1, p: 1 }} alignItems="center">
<Typography variant="h5"><strong>Release Access</strong></Typography>
</Grid2>
<Grid2 container sx={{ flexGrow: 1, p: 1 }} alignItems="center">
<Typography variant="body1">Would you like to release the access <code>{feToken}</code> ?</Typography>
</Grid2>
<Grid2 container sx={{ flexGrow: 1, p: 1 }} alignItems="center">
<FormControlLabel control={<Checkbox checked={checked} onChange={toggleChecked} />} label={<p>I confirm the release of <code>{feToken}</code></p>} sx={{ mt: 2 }} />
</Grid2>
<Grid2 container sx={{ flexGrow: 1 }} alignItems="center">
<Button color="error" variant="contained" disabled={!checked} onClick={action}>Release</Button>
</Grid2>
</Box>
</Modal>
);
}

interface AccessPanelProps {
access: Node;
Expand All @@ -14,6 +61,33 @@ interface AccessPanelProps {
const AccessPanel = ({ access }: AccessPanelProps) => {
const user = useStore((state) => state.user);
const [detail, setDetail] = useState<Frontend>(null);
const [releaseAccessOpen, setReleaseAccessOpen] = useState(false);

const openReleaseAccess = () => {
setReleaseAccessOpen(true);
}

const closeReleaseAccess = () => {
setReleaseAccessOpen(false);
}

const releaseAccess = () => {
if(detail && detail.token) {
let cfg = new Configuration({
headers: {
"X-TOKEN": user.token
}
});
let shareApi = new ShareApi(cfg);
shareApi.unaccess({body: {frontendToken: detail.token, envZId: detail.zId, shrToken: detail.shrToken}})
.then(d => {
setReleaseAccessOpen(false);
})
.catch(e => {
console.log("releaseAccess", e);
});
}
}

useEffect(() => {
let cfg = new Configuration({
Expand Down Expand Up @@ -45,26 +119,29 @@ const AccessPanel = ({ access }: AccessPanelProps) => {
}

return (
<Typography component="div">
<Grid2 container spacing={2}>
<Grid2 >
<Grid2 container sx={{ flexGrow: 1, p: 1 }} alignItems="center">
<Grid2 display="flex"><AccessIcon sx={{ fontSize: 30, mr: 0.5 }}/></Grid2>
<Grid2 display="flex" component="h3">{String(access.data.label)}</Grid2>
</Grid2>
<Grid2 container sx={{ flexGrow: 1, mb: 3 }} alignItems="left">
<Tooltip title="Release Access">
<Button variant="contained" color="error"><DeleteIcon /></Button>
</Tooltip>
</Grid2>
<Grid2 container sx={{ flexGrow: 1 }}>
<Grid2 display="flex">
<PropertyTable object={detail} custom={customProperties} labels={labels} />
<>
<Typography component="div">
<Grid2 container spacing={2}>
<Grid2 >
<Grid2 container sx={{ flexGrow: 1, p: 1 }} alignItems="center">
<Grid2 display="flex"><AccessIcon sx={{ fontSize: 30, mr: 0.5 }}/></Grid2>
<Grid2 display="flex" component="h3">{String(access.data.label)}</Grid2>
</Grid2>
<Grid2 container sx={{ flexGrow: 1, mb: 3 }} alignItems="left">
<Tooltip title="Release Access">
<Button variant="contained" color="error" onClick={openReleaseAccess}><DeleteIcon /></Button>
</Tooltip>
</Grid2>
<Grid2 container sx={{ flexGrow: 1 }}>
<Grid2 display="flex">
<PropertyTable object={detail} custom={customProperties} labels={labels} />
</Grid2>
</Grid2>
</Grid2>
</Grid2>
</Grid2>
</Typography>
</Typography>
<ReleaseAccessModal close={closeReleaseAccess} isOpen={releaseAccessOpen} detail={detail} action={releaseAccess} />
</>
);
}

Expand Down
18 changes: 14 additions & 4 deletions ui100/src/model/graph.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,16 +126,26 @@ export const mergeGraph = (oldVov: Graph, u: User, limited: boolean, newOv: Over

let outNodes = [];
if(oldVov.nodes) {
outNodes = oldVov.nodes.filter(oldNode => newVov.nodes.find(newNode => newNode.id === oldNode.id && newNode.data.limited == oldNode.data.limited && newNode.data.label === oldNode.data.label));
outNodes = oldVov.nodes.filter(oldNode => newVov.nodes.find(newNode => newNode.id === oldNode.id
&& newNode.data.accessed === oldNode.data.accessed
&& newNode.data.ownedShare === oldNode.data.ownedShare
&& newNode.data.limited === oldNode.data.limited
&& newNode.data.label === oldNode.data.label));
}
let outEdges = [];
if(oldVov.edges) {
outEdges = oldVov.edges.filter(oldEdge => newVov.edges.find(newEdge => newEdge.target === oldEdge.target && newEdge.source === oldEdge.source));
outEdges = oldVov.edges.filter(oldEdge => newVov.edges.find(newEdge => newEdge.target === oldEdge.target
&& newEdge.source === oldEdge.source));
}

// and then do the opposite; add any nodes that are in the new overview, but missing from the old overview.
outNodes.push(...newVov.nodes.filter(newNode => !outNodes.find(oldNode => oldNode.id === newNode.id && oldNode.data.limited === newNode.data.limited && oldNode.data.label === newNode.data.label)));
outEdges.push(...newVov.edges.filter(newEdge => !outEdges.find(oldEdge => oldEdge.target === newEdge.target && oldEdge.source === newEdge.source)));
outNodes.push(...newVov.nodes.filter(newNode => !outNodes.find(oldNode => oldNode.id === newNode.id
&& oldNode.data.accessed == newNode.data.accessed
&& oldNode.data.ownedShare === newNode.data.ownedShare
&& oldNode.data.limited === newNode.data.limited
&& oldNode.data.label === newNode.data.label)));
outEdges.push(...newVov.edges.filter(newEdge => !outEdges.find(oldEdge => oldEdge.target === newEdge.target
&& oldEdge.source === newEdge.source)));

newVov.nodes = outNodes;
newVov.edges = outEdges;
Expand Down

0 comments on commit 6981e81

Please sign in to comment.