From e4253e3558958ce41356f01aaab7b5f9c4db6434 Mon Sep 17 00:00:00 2001 From: Gustavo Massaneiro Date: Wed, 5 Jan 2022 17:04:46 -0300 Subject: [PATCH] new ServiceMapModal component --- .../ServiceMapModal/ServiceMapModal.tsx | 116 ++++++++++++++++++ ui/src/components/TrafficPage.tsx | 20 ++- 2 files changed, 124 insertions(+), 12 deletions(-) create mode 100644 ui/src/components/ServiceMapModal/ServiceMapModal.tsx diff --git a/ui/src/components/ServiceMapModal/ServiceMapModal.tsx b/ui/src/components/ServiceMapModal/ServiceMapModal.tsx new file mode 100644 index 000000000..88433ad8f --- /dev/null +++ b/ui/src/components/ServiceMapModal/ServiceMapModal.tsx @@ -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 = ({ isOpen, onClose, api }) => { + const [isLoading, setIsLoading] = useState(true); + const [graphData, setGraphData] = useState({ + 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 ( + + + {/* */} +
+ {isLoading &&
+ spinner +
} + {!isLoading && } +
+ {/*
*/} +
+
+ ); + +} \ No newline at end of file diff --git a/ui/src/components/TrafficPage.tsx b/ui/src/components/TrafficPage.tsx index 5ff3bd4fd..5814d9dc1 100644 --- a/ui/src/components/TrafficPage.tsx +++ b/ui/src/components/TrafficPage.tsx @@ -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 = ({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 = ({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 = ({setAnalyzeStatus, onTLS color: "#fff", textTransform: "none", }} - onClick={openServiceMap} + onClick={openServiceMapModal} > Service Map @@ -400,6 +395,7 @@ export const TrafficPage: React.FC = ({setAnalyzeStatus, onTLS pauseOnFocusLoss draggable pauseOnHover /> + {serviceMapModalOpen && setServiceMapModalOpen(false)} api={api} />} ) };