new ServiceMapModal component

This commit is contained in:
Gustavo Massaneiro
2022-01-05 17:04:46 -03:00
parent dc891053b9
commit e4253e3558
2 changed files with 124 additions and 12 deletions

View File

@@ -0,0 +1,116 @@
import React, { useState, useEffect } from "react";
import { Box, Fade, Modal, Backdrop } from "@material-ui/core";
import Api from "../../helpers/api";
import spinnerStyle from '../style/Spinner.module.sass';
import spinnerImg from '../assets/spinner.svg';
import ForceGraph2D, { GraphData } from 'react-force-graph-2d';
interface ServiceMapModalProps {
isOpen: boolean;
onClose: () => void;
api: Api
}
interface ServiceMapNode {
name: string;
protocol: string;
count: number;
}
interface ServiceMapEdge {
source: string;
destination: string;
count: number;
}
interface ServiceMapGraph {
nodes: ServiceMapNode[];
edges: ServiceMapEdge[];
}
export const ServiceMapModal: React.FC<ServiceMapModalProps> = ({ isOpen, onClose, api }) => {
const [isLoading, setIsLoading] = useState<boolean>(true);
const [graphData, setGraphData] = useState<GraphData>({
nodes: [],
links: []
});
const style = {
position: 'absolute',
top: '10%',
left: '50%',
transform: 'translate(-50%, 0%)',
width: '80vw',
bgcolor: 'background.paper',
borderRadius: '5px',
boxShadow: 24,
p: 4,
color: '#000',
};
useEffect(() => {
(async () => {
try {
const serviceMapData: ServiceMapGraph = await api.serviceMapData()
let data: GraphData = {
nodes: [],
links: []
}
for (let i = 0; i < serviceMapData.nodes.length; i++) {
data.nodes.push({
id: serviceMapData.nodes[i].name
});
}
for (let i = 0; i < serviceMapData.edges.length; i++) {
data.links.push({
source: serviceMapData.edges[i].source,
target: serviceMapData.edges[i].destination
});
}
setGraphData(data)
setIsLoading(false)
} catch (error) {
console.error(error);
}
})()
}, [api]);
return (
<Modal
aria-labelledby="transition-modal-title"
aria-describedby="transition-modal-description"
open={isOpen}
onClose={onClose}
closeAfterTransition
BackdropComponent={Backdrop}
BackdropProps={{
timeout: 500,
}}
style={{ overflow: 'auto' }}
>
<Fade in={isOpen}>
{/* <Box sx={style}> */}
<div>
{isLoading && <div className={spinnerStyle.spinnerContainer}>
<img alt="spinner" src={spinnerImg} style={{ height: 50 }} />
</div>}
{!isLoading && <ForceGraph2D
graphData={graphData}
linkDirectionalArrowLength={3.5}
linkDirectionalArrowRelPos={1}
linkCurvature={0.25}
/>}
</div>
{/* </Box> */}
</Fade>
</Modal>
);
}

View File

@@ -9,10 +9,11 @@ import playIcon from './assets/run.svg';
import pauseIcon from './assets/pause.svg';
import variables from '../variables.module.scss';
import {StatusBar} from "./UI/StatusBar";
import Api, {MizuApiURL, MizuWebsocketURL} from "../helpers/api";
import Api, {MizuWebsocketURL} from "../helpers/api";
import { ToastContainer, toast } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';
import debounce from 'lodash/debounce';
import { ServiceMapModal } from "./ServiceMapModal/ServiceMapModal";
const useLayoutStyles = makeStyles(() => ({
details: {
@@ -60,6 +61,7 @@ export const TrafficPage: React.FC<TrafficPageProps> = ({setAnalyzeStatus, onTLS
const [tappingStatus, setTappingStatus] = useState(null);
const [serviceMapStatus, setServiceMapStatus] = useState(false);
const [serviceMapModalOpen, setServiceMapModalOpen] = useState(false);
const [isSnappedToBottom, setIsSnappedToBottom] = useState(true);
@@ -274,22 +276,15 @@ export const TrafficPage: React.FC<TrafficPageProps> = ({setAnalyzeStatus, onTLS
const serviceMapStatusResponse = await api.serviceMapStatus();
if (serviceMapStatusResponse["status"] === "enabled") {
setServiceMapStatus(true);
} else {
setServiceMapStatus(false);
}
}
} catch(error) {
setServiceMapStatus(false);
console.error(error);
}
})()
}, []);
const openServiceMap = debounce(() => {
if (serviceMapStatus) {
const url = `${MizuApiURL}servicemap/render`
window.open(url, "_blank")
}
// TODO: toast error message?
const openServiceMapModal = debounce(() => {
setServiceMapModalOpen(true)
}, 500);
const resetServiceMap = debounce(async () => {
@@ -328,7 +323,7 @@ export const TrafficPage: React.FC<TrafficPageProps> = ({setAnalyzeStatus, onTLS
color: "#fff",
textTransform: "none",
}}
onClick={openServiceMap}
onClick={openServiceMapModal}
>
Service Map
</Button>
@@ -400,6 +395,7 @@ export const TrafficPage: React.FC<TrafficPageProps> = ({setAnalyzeStatus, onTLS
pauseOnFocusLoss
draggable
pauseOnHover />
{serviceMapModalOpen && <ServiceMapModal isOpen={serviceMapModalOpen} onClose={() => setServiceMapModalOpen(false)} api={api} />}
</div>
)
};