mirror of https://github.com/EdgeVPNio/portal.git
Merge branch 'reduxChanges' of https://github.com/EdgeVPNio/portal into reduxChanges
commit
e6ff6d4648
|
@ -3,7 +3,7 @@ import Card from "react-bootstrap/Card";
|
||||||
import "bootstrap/dist/css/bootstrap.min.css";
|
import "bootstrap/dist/css/bootstrap.min.css";
|
||||||
import Accordion from "react-bootstrap/Accordion";
|
import Accordion from "react-bootstrap/Accordion";
|
||||||
import Button from "react-bootstrap/Button";
|
import Button from "react-bootstrap/Button";
|
||||||
import DowmArrow from "../images/icons/down-arrow-ic.svg";
|
import DownArrow from "../images/icons/down-arrow-ic.svg";
|
||||||
import UpArrow from "../images/icons/up-arrow-ic.svg";
|
import UpArrow from "../images/icons/up-arrow-ic.svg";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ class CollapsibleButton extends React.Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.isToggle = false;
|
this.isToggle = false;
|
||||||
this.accordionStyle = this.props.isOpen ? "block" : "none"
|
this.accordionStyle = this.props.isOpen ? "block" : "none";
|
||||||
}
|
}
|
||||||
componentDidUpdate(prevProps, prevState) {
|
componentDidUpdate(prevProps, prevState) {
|
||||||
if (this.props.selectedOverlayId !== prevProps.selectedOverlayId) {
|
if (this.props.selectedOverlayId !== prevProps.selectedOverlayId) {
|
||||||
|
@ -28,7 +28,7 @@ class CollapsibleButton extends React.Component {
|
||||||
handleOnClick(){
|
handleOnClick(){
|
||||||
this.isToggle = !this.isToggle;
|
this.isToggle = !this.isToggle;
|
||||||
this.accordionStyle = this.isToggle ? "block" : "none";
|
this.accordionStyle = this.isToggle ? "block" : "none";
|
||||||
};
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
|
@ -54,7 +54,7 @@ class CollapsibleButton extends React.Component {
|
||||||
{this.props.isToggle ? (
|
{this.props.isToggle ? (
|
||||||
<img className="arrow" src={UpArrow} alt="up-arrow" />
|
<img className="arrow" src={UpArrow} alt="up-arrow" />
|
||||||
) : (
|
) : (
|
||||||
<img className="arrow" src={DowmArrow} alt="down-arrow" />
|
<img className="arrow" src={DownArrow} alt="down-arrow" />
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -0,0 +1,54 @@
|
||||||
|
import React from "react";
|
||||||
|
import DownArrow from "../images/icons/down-arrow-ic.svg";
|
||||||
|
import UpArrow from "../images/icons/up-arrow-ic.svg";
|
||||||
|
import { connect } from "react-redux";
|
||||||
|
|
||||||
|
class CustomCollapsibleButton extends React.Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.state = {
|
||||||
|
open: false,
|
||||||
|
};
|
||||||
|
if(this.props.hasOwnProperty("expanded")){
|
||||||
|
this.state.open = this.props.expanded;
|
||||||
|
}
|
||||||
|
this.togglePanel = this.togglePanel.bind(this);
|
||||||
|
}
|
||||||
|
componentDidUpdate() {}
|
||||||
|
|
||||||
|
componentDidMount() {}
|
||||||
|
|
||||||
|
componentWillUnmount() {}
|
||||||
|
|
||||||
|
togglePanel(e) {
|
||||||
|
this.setState({ open: !this.state.open });
|
||||||
|
}
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<br/>
|
||||||
|
<div className="collapse-wrapper">
|
||||||
|
<div onClick={(e) => this.togglePanel(e)} className="collapse-header">
|
||||||
|
<div className="row">
|
||||||
|
<div className="col">{this.props.title}</div>
|
||||||
|
<div className="col" style={{ textAlign: "right" }}>
|
||||||
|
{this.state.open ? (
|
||||||
|
<img className="arrow" src={UpArrow} alt="up-arrow" />
|
||||||
|
) : (
|
||||||
|
<img className="arrow" src={DownArrow} alt="down-arrow" />
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{this.state.open ? (
|
||||||
|
<div className="collapse-content">
|
||||||
|
{this.props.description}
|
||||||
|
{this.props.children}
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export default CustomCollapsibleButton;
|
|
@ -1,19 +1,13 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import ReactDOM from "react-dom";
|
import ReactDOM from "react-dom";
|
||||||
//import cytoscape from "cytoscape";
|
|
||||||
import Cytoscape from "react-cytoscapejs";
|
import Cytoscape from "react-cytoscapejs";
|
||||||
//import CytoscapeComponent from "react-cytoscapejs";
|
import CollapseButton from "./CustomCollapsibleButton";
|
||||||
import CollapsibleButton from "./CollapsibleButton";
|
|
||||||
import cytoscapeStyle from "./cytoscapeStyle.js";
|
import cytoscapeStyle from "./cytoscapeStyle.js";
|
||||||
import { Typeahead } from "react-bootstrap-typeahead";
|
import { Typeahead } from "react-bootstrap-typeahead";
|
||||||
//import { Spinner } from "react-bootstrap";
|
|
||||||
import SideBar from "./Sidebar";
|
import SideBar from "./Sidebar";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
import { setCyElements } from "../features/evio/evioSlice";
|
import { setCyElements } from "../features/evio/evioSlice";
|
||||||
import {
|
import {
|
||||||
//setSelectedElement,
|
|
||||||
//clearSelectedElement,
|
|
||||||
//elementTypes,
|
|
||||||
setRedrawGraph,
|
setRedrawGraph,
|
||||||
} from "../features/evio/evioSlice";
|
} from "../features/evio/evioSlice";
|
||||||
import { setCurrentView } from "../features/view/viewSlice";
|
import { setCurrentView } from "../features/view/viewSlice";
|
||||||
|
@ -28,9 +22,7 @@ const nodeStates = {
|
||||||
class TopologyView extends React.Component {
|
class TopologyView extends React.Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = {
|
this.isSwapToggle = false;
|
||||||
isSwapToggle: false,
|
|
||||||
};
|
|
||||||
this.intervalId = null;
|
this.intervalId = null;
|
||||||
this.timeoutId = null;
|
this.timeoutId = null;
|
||||||
this.autoRefresh = this.props.autoUpdate;
|
this.autoRefresh = this.props.autoUpdate;
|
||||||
|
@ -211,8 +203,6 @@ class TopologyView extends React.Component {
|
||||||
.not(selectedElement);
|
.not(selectedElement);
|
||||||
let adj = selectedElement.neighborhood();
|
let adj = selectedElement.neighborhood();
|
||||||
let abscomp = adj.absoluteComplement();
|
let abscomp = adj.absoluteComplement();
|
||||||
// console.log("nei", neighborhood, "adj", adj);
|
|
||||||
// console.log("excluded", excluded, "abscomp", abscomp);
|
|
||||||
} else if (selectedElement.isEdge()) {
|
} else if (selectedElement.isEdge()) {
|
||||||
neighborhood = selectedElement.connectedNodes().union(selectedElement);
|
neighborhood = selectedElement.connectedNodes().union(selectedElement);
|
||||||
excluded = this.cy
|
excluded = this.cy
|
||||||
|
@ -233,7 +223,6 @@ class TopologyView extends React.Component {
|
||||||
var data = await res.json();
|
var data = await res.json();
|
||||||
var nodeLocation =
|
var nodeLocation =
|
||||||
data.results[data.results.length - 1].formatted_address;
|
data.results[data.results.length - 1].formatted_address;
|
||||||
console.log("formatted_address", nodeLocation);
|
|
||||||
return nodeLocation.slice(7, nodeLocation.length);
|
return nodeLocation.slice(7, nodeLocation.length);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
return "Unknown";
|
return "Unknown";
|
||||||
|
@ -277,26 +266,20 @@ class TopologyView extends React.Component {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
getNotReportingNodeDetails(notReportingNode) {
|
getNotReportingNodeDetails(cyNode) {
|
||||||
var nodeContent = (
|
var nodeContent = (
|
||||||
<CollapsibleButton
|
<CollapseButton title={cyNode.data().label}>
|
||||||
id={notReportingNode.data().id + "Btn"}
|
|
||||||
className="detailsNodeBtn"
|
|
||||||
key={notReportingNode.data().id + "Btn"}
|
|
||||||
name={notReportingNode.data().label}
|
|
||||||
isOpen
|
|
||||||
>
|
|
||||||
<div>
|
<div>
|
||||||
<h5>{notReportingNode.data().label}</h5>
|
<h5>{cyNode.data().label}</h5>
|
||||||
<div className="DetailsLabel">Node ID</div>
|
<div className="DetailsLabel">Node ID</div>
|
||||||
<label id="valueLabel">{notReportingNode.data().id}</label>
|
<label id="valueLabel">{cyNode.data().id}</label>
|
||||||
<div className="DetailsLabel">State</div>
|
<div className="DetailsLabel">State</div>
|
||||||
<label id="valueLabel">{notReportingNode.data().state}</label>
|
<label id="valueLabel">{cyNode.data().state}</label>
|
||||||
<div className="DetailsLabel">Location</div>
|
<div className="DetailsLabel">Location</div>
|
||||||
<label id="valueLabel">{"Unknown"}</label>
|
<label id="valueLabel">{cyNode.data().location}</label>
|
||||||
<hr style={{ backgroundColor: "#486186" }} />
|
<hr style={{ backgroundColor: "#486186" }} />
|
||||||
</div>
|
</div>
|
||||||
</CollapsibleButton>
|
</CollapseButton>
|
||||||
);
|
);
|
||||||
return nodeContent;
|
return nodeContent;
|
||||||
}
|
}
|
||||||
|
@ -309,14 +292,11 @@ class TopologyView extends React.Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var nodeContent = (
|
var nodeContent = (
|
||||||
<CollapsibleButton
|
<CollapseButton
|
||||||
id={cyNode.data().label + "Btn"}
|
title={cyNode.data().label}
|
||||||
className="detailsNodeBtn"
|
expanded={true}
|
||||||
key={cyNode.data().label + "Btn"}
|
description={
|
||||||
name={cyNode.data().label}
|
|
||||||
>
|
|
||||||
<div>
|
<div>
|
||||||
<h5>{cyNode.data().label}</h5>
|
|
||||||
<div id="DetailsLabel">Node ID</div>
|
<div id="DetailsLabel">Node ID</div>
|
||||||
<label id="valueLabel">{cyNode.data().id}</label>
|
<label id="valueLabel">{cyNode.data().id}</label>
|
||||||
<div className="DetailsLabel">State</div>
|
<div className="DetailsLabel">State</div>
|
||||||
|
@ -324,23 +304,19 @@ class TopologyView extends React.Component {
|
||||||
<div className="DetailsLabel">Location</div>
|
<div className="DetailsLabel">Location</div>
|
||||||
<label id="valueLabel">{cyNode.data().location}</label>
|
<label id="valueLabel">{cyNode.data().location}</label>
|
||||||
<hr style={{ backgroundColor: "#486186" }} />
|
<hr style={{ backgroundColor: "#486186" }} />
|
||||||
<div id="connectedNode" style={{ overflow: "auto" }}>
|
<div id="connectedNode" style={{ overflow: "auto" }}></div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
>
|
||||||
{sidebarNodeslist.map((connectedNode) => {
|
{sidebarNodeslist.map((connectedNode) => {
|
||||||
try {
|
try {
|
||||||
let [connectedlinkDetail, tunnelId] =
|
var [connectedlinkDetail, tunnelId] = this.getConnectedLinkDetails(
|
||||||
this.getConnectedLinkDetails(
|
|
||||||
cyNode,
|
cyNode,
|
||||||
connectedNode,
|
connectedNode,
|
||||||
connectedEdges
|
connectedEdges
|
||||||
);
|
);
|
||||||
var connectedNodeBtn = (
|
var connectedNodeBtn = (
|
||||||
<CollapsibleButton
|
<CollapseButton title={connectedNode.label}>
|
||||||
id={connectedNode.label + "Btn"}
|
|
||||||
className="connectedNodeBtn"
|
|
||||||
key={connectedNode.label + "Btn"}
|
|
||||||
eventKey={connectedNode.label}
|
|
||||||
name={connectedNode.label}
|
|
||||||
>
|
|
||||||
<div className="DetailsLabel">Node ID</div>
|
<div className="DetailsLabel">Node ID</div>
|
||||||
<label id="valueLabel">{connectedNode.id}</label>
|
<label id="valueLabel">{connectedNode.id}</label>
|
||||||
<div className="DetailsLabel">Tunnel ID</div>
|
<div className="DetailsLabel">Tunnel ID</div>
|
||||||
|
@ -363,18 +339,16 @@ class TopologyView extends React.Component {
|
||||||
connectedlinkDetail.Type.length
|
connectedlinkDetail.Type.length
|
||||||
)}
|
)}
|
||||||
</label>
|
</label>
|
||||||
</CollapsibleButton>
|
</CollapseButton>
|
||||||
);
|
);
|
||||||
|
|
||||||
return connectedNodeBtn;
|
return connectedNodeBtn;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log(e);
|
console.log(e);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
})}
|
})}
|
||||||
</div>
|
<br />
|
||||||
</div>
|
</CollapseButton>
|
||||||
</CollapsibleButton>
|
|
||||||
);
|
);
|
||||||
return nodeContent;
|
return nodeContent;
|
||||||
}
|
}
|
||||||
|
@ -382,13 +356,7 @@ class TopologyView extends React.Component {
|
||||||
getNotConnectedNodeDetails(cyNode) {
|
getNotConnectedNodeDetails(cyNode) {
|
||||||
var nodeContent = (
|
var nodeContent = (
|
||||||
//No tunnels node
|
//No tunnels node
|
||||||
<CollapsibleButton
|
<CollapseButton title={cyNode.data().label} expanded={true}>
|
||||||
id={cyNode.data().id + "Btn"}
|
|
||||||
className="detailsNodeBtn"
|
|
||||||
key={cyNode.data().id + "Btn"}
|
|
||||||
name={cyNode.data().label}
|
|
||||||
isOpen
|
|
||||||
>
|
|
||||||
<div>
|
<div>
|
||||||
<h5>{cyNode.data().label}</h5>
|
<h5>{cyNode.data().label}</h5>
|
||||||
<div className="DetailsLabel">Node ID</div>
|
<div className="DetailsLabel">Node ID</div>
|
||||||
|
@ -399,7 +367,7 @@ class TopologyView extends React.Component {
|
||||||
<label id="valueLabel">{cyNode.data().location}</label>
|
<label id="valueLabel">{cyNode.data().location}</label>
|
||||||
<hr style={{ backgroundColor: "#486186" }} />
|
<hr style={{ backgroundColor: "#486186" }} />
|
||||||
</div>
|
</div>
|
||||||
</CollapsibleButton>
|
</CollapseButton>
|
||||||
);
|
);
|
||||||
return nodeContent;
|
return nodeContent;
|
||||||
}
|
}
|
||||||
|
@ -408,6 +376,27 @@ class TopologyView extends React.Component {
|
||||||
var connectedNodes = adj.nodes();
|
var connectedNodes = adj.nodes();
|
||||||
var connectedEdges = adj.edges();
|
var connectedEdges = adj.edges();
|
||||||
var nodeDetails = null;
|
var nodeDetails = null;
|
||||||
|
if(cyNode.data().hasOwnProperty("location")){
|
||||||
|
if (cyNode.data("state") === nodeStates.notReporting) {
|
||||||
|
nodeDetails = this.getNotReportingNodeDetails(cyNode);
|
||||||
|
} else if (cyNode.data("state") === nodeStates.connected) {
|
||||||
|
nodeDetails = this.getConnectedNodeDetails(
|
||||||
|
cyNode,
|
||||||
|
connectedNodes,
|
||||||
|
connectedEdges
|
||||||
|
);
|
||||||
|
} else if (cyNode.data("state") === nodeStates.noTunnels) {
|
||||||
|
nodeDetails = this.getNotConnectedNodeDetails(cyNode);
|
||||||
|
}
|
||||||
|
ReactDOM.render(
|
||||||
|
<div>
|
||||||
|
<div> Node Details </div>
|
||||||
|
<div> {nodeDetails} </div>
|
||||||
|
</div>,
|
||||||
|
document.getElementById("sideBarContent")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else{
|
||||||
this.queryGeoCoordinates(cyNode.data("coords"))
|
this.queryGeoCoordinates(cyNode.data("coords"))
|
||||||
.then((loc) => {
|
.then((loc) => {
|
||||||
cyNode.data("location", loc);
|
cyNode.data("location", loc);
|
||||||
|
@ -433,22 +422,23 @@ class TopologyView extends React.Component {
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
console.warn(err);
|
console.warn(err);
|
||||||
});
|
});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
getConnectedLinkDetails(source, tgt, connectedEdges) {
|
getConnectedLinkDetails(source, tgt, connectedEdges) {
|
||||||
for (var edge of connectedEdges) {
|
for (var edge of connectedEdges) {
|
||||||
if (
|
if (
|
||||||
(source.data().id === edge.data("source") &&
|
(source.data().id === edge._private.data.source &&
|
||||||
tgt.id === edge.data("target")) ||
|
tgt.id === edge._private.data.target) ||
|
||||||
(source.data().id === edge.data.target &&
|
(source.data().id === edge._private.data.target &&
|
||||||
tgt.id === edge.data("source"))
|
tgt.id === edge._private.data.source)
|
||||||
) {
|
) {
|
||||||
for (var descriptorItem of edge.data("descriptor")) {
|
for (var descriptorItem of edge._private.data.descriptor) {
|
||||||
if (
|
if (
|
||||||
source.data().id === descriptorItem.Source &&
|
source.data().id === descriptorItem.Source &&
|
||||||
tgt.id === descriptorItem.Target
|
tgt.id === descriptorItem.Target
|
||||||
) {
|
) {
|
||||||
return [descriptorItem, edge.data("id")];
|
return [descriptorItem, edge._private.data.id];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -480,7 +470,7 @@ class TopologyView extends React.Component {
|
||||||
.data;
|
.data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (this.state.isSwapToggle === false) {
|
if (this.isSwapToggle === false) {
|
||||||
return [sourceNodeLinkDetails, srcNode, tgtNode];
|
return [sourceNodeLinkDetails, srcNode, tgtNode];
|
||||||
} else {
|
} else {
|
||||||
//if swapbutton toggled then swap source and node details
|
//if swapbutton toggled then swap source and node details
|
||||||
|
@ -490,7 +480,7 @@ class TopologyView extends React.Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getTunnelWithBothReportingNodes(selectedTunnel) {
|
getTunnelWithBothReportingNodes(selectedTunnel, adj) {
|
||||||
var LocalEndpointInternal;
|
var LocalEndpointInternal;
|
||||||
var [sourceNodeLinkDetails, srcNode, tgtNode] =
|
var [sourceNodeLinkDetails, srcNode, tgtNode] =
|
||||||
this.getSourceAndTargetDetails(selectedTunnel);
|
this.getSourceAndTargetDetails(selectedTunnel);
|
||||||
|
@ -501,69 +491,42 @@ class TopologyView extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
var linkContent = (
|
var linkContent = (
|
||||||
<CollapsibleButton
|
<CollapseButton title={sourceNodeLinkDetails.TapName} expanded={true}>
|
||||||
id={sourceNodeLinkDetails.TapName + "Btn"}
|
|
||||||
className="detailsLinkBtn"
|
|
||||||
key={selectedTunnel.id + "Btn"}
|
|
||||||
name={sourceNodeLinkDetails.TapName}
|
|
||||||
isOpen={true}
|
|
||||||
>
|
|
||||||
<div>
|
<div>
|
||||||
<h5>{sourceNodeLinkDetails.TapName}</h5>
|
|
||||||
<div className="row">
|
<div className="row">
|
||||||
<div className="col-10" style={{ paddingRight: "0" }}>
|
<div className="col-10" style={{ paddingRight: "0" }}>
|
||||||
<CollapsibleButton
|
<CollapseButton
|
||||||
id={srcNode.label + "Btn"}
|
title={srcNode.label}
|
||||||
className="sourceNodeBtn"
|
|
||||||
key={srcNode.label + "Btn"}
|
|
||||||
eventKey={srcNode.label + "Btn"}
|
|
||||||
name={srcNode.label}
|
|
||||||
style={{
|
|
||||||
marginBottom: "2.5%",
|
|
||||||
backgroundColor: "#8aa626",
|
|
||||||
border: `solid #8aa626`,
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<div className="DetailsLabel">Node ID</div>
|
<div className="DetailsLabel">Node ID</div>
|
||||||
<label id="valueLabel">{srcNode.id.slice(0, 7)}</label>
|
<label id="valueLabel">{srcNode.id.slice(0, 7)}</label>
|
||||||
<div className="DetailsLabel">State</div>
|
<div className="DetailsLabel">State</div>
|
||||||
<label id="valueLabel">{srcNode.state}</label>
|
<label id="valueLabel">{srcNode.state}</label>
|
||||||
<div className="DetailsLabel">Location</div>
|
<div className="DetailsLabel">Location</div>
|
||||||
{/* <label id="valueLabel">{sourceLocation.slice(7, sourceLocation.length)}</label> */}
|
<label id="valueLabel">{srcNode.location}</label>
|
||||||
<label id="valueLabel">{"Unknown"}</label>
|
</CollapseButton>
|
||||||
</CollapsibleButton>
|
|
||||||
|
|
||||||
<CollapsibleButton
|
<CollapseButton
|
||||||
id={tgtNode.label + "Btn"}
|
title={tgtNode.label}
|
||||||
className="targetNodeBtn"
|
|
||||||
key={tgtNode.label + "Btn"}
|
|
||||||
eventKey={tgtNode.label + "Btn"}
|
|
||||||
name={tgtNode.label}
|
|
||||||
style={{
|
|
||||||
marginBottom: "2.5%",
|
|
||||||
backgroundColor: "#8aa626",
|
|
||||||
border: `solid #8aa626`,
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<div className="DetailsLabel">Node ID</div>
|
<div className="DetailsLabel">Node ID</div>
|
||||||
<label id="valueLabel">{tgtNode.id.slice(0, 7)}</label>
|
<label id="valueLabel">{tgtNode.id.slice(0, 7)}</label>
|
||||||
<div className="DetailsLabel">State</div>
|
<div className="DetailsLabel">State</div>
|
||||||
<label id="valueLabel">{tgtNode.state}</label>
|
<label id="valueLabel">{tgtNode.state}</label>
|
||||||
<div className="DetailsLabel">Location</div>
|
<div className="DetailsLabel">Location</div>
|
||||||
{/* <label id="valueLabel">{targetLocation.slice(7, targetLocation.length)}</label> */}
|
<label id="valueLabel">{tgtNode.location}</label>
|
||||||
<label id="valueLabel">{"Unknown"}</label>
|
</CollapseButton>
|
||||||
</CollapsibleButton>
|
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
className="col"
|
className="col"
|
||||||
style={{ margin: "auto", padding: "0", textAlign: "center" }}
|
style={{ margin: "auto", padding: "0", textAlign: "center" }}
|
||||||
>
|
>
|
||||||
<button onClick={this.handleSwitch} id="switchBtn" />
|
<button onClick={this.handleSwitch.bind(this, selectedTunnel, adj)} id="switchBtn" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<hr style={{ backgroundColor: "#486186" }} />
|
<hr style={{ backgroundColor: "#486186" }} />
|
||||||
<div className="DetailsLabel">Tunnel ID</div>
|
<div className="DetailsLabel">Tunnel ID</div>
|
||||||
<label id="valueLabel">{selectedTunnel.id}</label>
|
<label id="valueLabel">{selectedTunnel.data().id}</label>
|
||||||
<div className="DetailsLabel">Interface Name</div>
|
<div className="DetailsLabel">Interface Name</div>
|
||||||
<label id="valueLabel">{sourceNodeLinkDetails.TapName}</label>
|
<label id="valueLabel">{sourceNodeLinkDetails.TapName}</label>
|
||||||
<div className="DetailsLabel">MAC</div>
|
<div className="DetailsLabel">MAC</div>
|
||||||
|
@ -597,12 +560,12 @@ class TopologyView extends React.Component {
|
||||||
{sourceNodeLinkDetails.RemoteEndpoint.External}
|
{sourceNodeLinkDetails.RemoteEndpoint.External}
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</CollapsibleButton>
|
</CollapseButton>
|
||||||
);
|
);
|
||||||
return linkContent;
|
return linkContent;
|
||||||
}
|
}
|
||||||
|
|
||||||
getTunnelWithEitherOneReportingNodes(selectedTunnel) {
|
getTunnelWithEitherOneReportingNodes(selectedTunnel, adj) {
|
||||||
var LocalEndpointInternal;
|
var LocalEndpointInternal;
|
||||||
var [sourceNodeLinkDetails, srcNode, tgtNode] =
|
var [sourceNodeLinkDetails, srcNode, tgtNode] =
|
||||||
this.getSourceAndTargetDetails(selectedTunnel);
|
this.getSourceAndTargetDetails(selectedTunnel);
|
||||||
|
@ -612,69 +575,44 @@ class TopologyView extends React.Component {
|
||||||
LocalEndpointInternal = sourceNodeLinkDetails.LocalEndpoint.Internal;
|
LocalEndpointInternal = sourceNodeLinkDetails.LocalEndpoint.Internal;
|
||||||
}
|
}
|
||||||
var linkContent = (
|
var linkContent = (
|
||||||
<CollapsibleButton
|
<CollapseButton
|
||||||
id={sourceNodeLinkDetails.TapName + "Btn"}
|
title={sourceNodeLinkDetails.TapName}
|
||||||
className="detailsLinkBtn"
|
expanded={true}
|
||||||
key={sourceNodeLinkDetails.TapName + "Btn"}
|
|
||||||
name={sourceNodeLinkDetails.TapName}
|
|
||||||
isOpen
|
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<h5>{sourceNodeLinkDetails.TapName}</h5>
|
|
||||||
<div className="row">
|
<div className="row">
|
||||||
<div className="col-10" style={{ paddingRight: "0" }}>
|
<div className="col-10" style={{ paddingRight: "0" }}>
|
||||||
<CollapsibleButton
|
<CollapseButton
|
||||||
id={srcNode.label + "Btn"}
|
title={srcNode.label}
|
||||||
className="sourceNodeBtn"
|
|
||||||
key={srcNode.label + "Btn"}
|
|
||||||
eventKey={srcNode.label + "Btn"}
|
|
||||||
name={srcNode.label}
|
|
||||||
style={{
|
|
||||||
marginBottom: "2.5%",
|
|
||||||
backgroundColor: "#8aa626",
|
|
||||||
border: `solid #8aa626`,
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<div className="DetailsLabel">Node ID</div>
|
<div className="DetailsLabel">Node ID</div>
|
||||||
<label id="valueLabel">{srcNode.id.slice(0, 7)}</label>
|
<label id="valueLabel">{srcNode.id.slice(0, 7)}</label>
|
||||||
<div className="DetailsLabel">State</div>
|
<div className="DetailsLabel">State</div>
|
||||||
<label id="valueLabel">{srcNode.state}</label>
|
<label id="valueLabel">{srcNode.state}</label>
|
||||||
<div className="DetailsLabel">Location</div>
|
<div className="DetailsLabel">Location</div>
|
||||||
{/* <label id="valueLabel">{sourceLocation.slice(7, sourceLocation.length)}</label> */}
|
<label id="valueLabel">{srcNode.location}</label>
|
||||||
<label id="valueLabel">{"Unknown"}</label>
|
</CollapseButton>
|
||||||
</CollapsibleButton>
|
|
||||||
|
|
||||||
<CollapsibleButton
|
<CollapseButton
|
||||||
id={tgtNode.label + "Btn"}
|
title={tgtNode.label} >
|
||||||
className="targetNodeBtn"
|
|
||||||
key={tgtNode.label + "Btn"}
|
|
||||||
eventKey={tgtNode.label + "Btn"}
|
|
||||||
name={tgtNode.label}
|
|
||||||
style={{
|
|
||||||
marginBottom: "2.5%",
|
|
||||||
backgroundColor: "#8aa626",
|
|
||||||
border: `solid #8aa626`,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div className="DetailsLabel">Node ID</div>
|
<div className="DetailsLabel">Node ID</div>
|
||||||
<label id="valueLabel">{tgtNode.id.slice(0, 7)}</label>
|
<label id="valueLabel">{tgtNode.id.slice(0, 7)}</label>
|
||||||
<div className="DetailsLabel">State</div>
|
<div className="DetailsLabel">State</div>
|
||||||
<label id="valueLabel">{tgtNode.state}</label>
|
<label id="valueLabel">{tgtNode.state}</label>
|
||||||
<div className="DetailsLabel">Location</div>
|
<div className="DetailsLabel">Location</div>
|
||||||
{/* <label id="valueLabel">{sourceLocation.slice(7, sourceLocation.length)}</label> */}
|
<label id="valueLabel">{tgtNode.location}</label>
|
||||||
<label id="valueLabel">{"Unknown"}</label>
|
</CollapseButton>
|
||||||
</CollapsibleButton>
|
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
className="col"
|
className="col"
|
||||||
style={{ margin: "auto", padding: "0", textAlign: "center" }}
|
style={{ margin: "auto", padding: "0", textAlign: "center" }}
|
||||||
>
|
>
|
||||||
<button onClick={this.handleSwitch} id="switchBtn" />
|
<button onClick={this.handleSwitch.bind(this, selectedTunnel, adj)} id="switchBtn" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<hr style={{ backgroundColor: "#486186" }} />
|
<hr style={{ backgroundColor: "#486186" }} />
|
||||||
<div className="DetailsLabel">Tunnel ID</div>
|
<div className="DetailsLabel">Tunnel ID</div>
|
||||||
<label id="valueLabel">{selectedTunnel.id}</label>
|
<label id="valueLabel">{selectedTunnel.data().id}</label>
|
||||||
<div className="DetailsLabel">Interface Name</div>
|
<div className="DetailsLabel">Interface Name</div>
|
||||||
<label id="valueLabel">{sourceNodeLinkDetails.TapName}</label>
|
<label id="valueLabel">{sourceNodeLinkDetails.TapName}</label>
|
||||||
<div className="DetailsLabel">MAC</div>
|
<div className="DetailsLabel">MAC</div>
|
||||||
|
@ -708,33 +646,30 @@ class TopologyView extends React.Component {
|
||||||
{sourceNodeLinkDetails.RemoteEndpoint.External}
|
{sourceNodeLinkDetails.RemoteEndpoint.External}
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</CollapsibleButton>
|
</CollapseButton>
|
||||||
);
|
);
|
||||||
return linkContent;
|
return linkContent;
|
||||||
}
|
}
|
||||||
|
|
||||||
getTunnelWithNoReportingNodes() {
|
getTunnelWithNoReportingNodes() {
|
||||||
var linkContentNR = (
|
var linkContentNR = (
|
||||||
<CollapsibleButton
|
<CollapseButton
|
||||||
id={"notReportingBtn"}
|
title={"Details"}
|
||||||
className="detailsLinkBtn"
|
expanded={true}
|
||||||
key={"notReportingBtn"}
|
|
||||||
name={"Details"}
|
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<label id="valueLabel">{"Data not available"}</label>
|
<label id="valueLabel">{"Data not available"}</label>
|
||||||
</div>
|
</div>
|
||||||
</CollapsibleButton>
|
</CollapseButton>
|
||||||
);
|
);
|
||||||
return linkContentNR;
|
return linkContentNR;
|
||||||
}
|
}
|
||||||
|
|
||||||
renderTunnelDetails = (cyEdge) => {
|
renderTunnelDetails = (cyEdge, adj) => {
|
||||||
var tunnelDetails;
|
var tunnelDetails;
|
||||||
var selectedTunnelNodesDetails = [];
|
var selectedTunnelNodesDetails = [];
|
||||||
try {
|
try {
|
||||||
var partitionElements = this.partitionElements(cyEdge);
|
for (var node of adj) {
|
||||||
for (var node of partitionElements.neighborhood) {
|
|
||||||
if (node._private.group === "nodes") {
|
if (node._private.group === "nodes") {
|
||||||
selectedTunnelNodesDetails.push(node.data());
|
selectedTunnelNodesDetails.push(node.data());
|
||||||
}
|
}
|
||||||
|
@ -743,14 +678,14 @@ class TopologyView extends React.Component {
|
||||||
selectedTunnelNodesDetails[0].state === nodeStates.connected &&
|
selectedTunnelNodesDetails[0].state === nodeStates.connected &&
|
||||||
selectedTunnelNodesDetails[1].state === nodeStates.connected
|
selectedTunnelNodesDetails[1].state === nodeStates.connected
|
||||||
) {
|
) {
|
||||||
tunnelDetails = this.getTunnelWithBothReportingNodes(cyEdge);
|
tunnelDetails = this.getTunnelWithBothReportingNodes(cyEdge, adj);
|
||||||
} else if (
|
} else if (
|
||||||
(selectedTunnelNodesDetails[0].state === nodeStates.connected &&
|
(selectedTunnelNodesDetails[0].state === nodeStates.connected &&
|
||||||
selectedTunnelNodesDetails[1].state === nodeStates.notReporting) ||
|
selectedTunnelNodesDetails[1].state === nodeStates.notReporting) ||
|
||||||
(selectedTunnelNodesDetails[0].state === nodeStates.notReporting &&
|
(selectedTunnelNodesDetails[0].state === nodeStates.notReporting &&
|
||||||
selectedTunnelNodesDetails[1].state === nodeStates.connected)
|
selectedTunnelNodesDetails[1].state === nodeStates.connected)
|
||||||
) {
|
) {
|
||||||
tunnelDetails = this.getTunnelWithEitherOneReportingNodes(cyEdge);
|
tunnelDetails = this.getTunnelWithEitherOneReportingNodes(cyEdge, adj);
|
||||||
} else if (
|
} else if (
|
||||||
selectedTunnelNodesDetails[0].state === nodeStates.notReporting &&
|
selectedTunnelNodesDetails[0].state === nodeStates.notReporting &&
|
||||||
selectedTunnelNodesDetails[1].state === nodeStates.notReporting
|
selectedTunnelNodesDetails[1].state === nodeStates.notReporting
|
||||||
|
@ -769,8 +704,9 @@ class TopologyView extends React.Component {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
handleSwitch = () => {
|
handleSwitch = (selectedTunnel, adj) => {
|
||||||
this.setState({ isSwapToggle: !this.state.isSwapToggle });
|
this.isSwapToggle= !this.isSwapToggle;
|
||||||
|
this.renderTunnelDetails(selectedTunnel, adj);
|
||||||
};
|
};
|
||||||
|
|
||||||
handleWheel(e) {
|
handleWheel(e) {
|
||||||
|
@ -819,7 +755,7 @@ class TopologyView extends React.Component {
|
||||||
if (this.props.zoomMax !== prevProps.zoomMax) {
|
if (this.props.zoomMax !== prevProps.zoomMax) {
|
||||||
this.cy.maxZoom(this.props.zoomMax);
|
this.cy.maxZoom(this.props.zoomMax);
|
||||||
}
|
}
|
||||||
if (this.props.redrawGraph !== prevState.redrawGraph) {
|
if (this.props.redrawGraph !== prevProps.redrawGraph) {
|
||||||
this.cy.center();
|
this.cy.center();
|
||||||
}
|
}
|
||||||
if (this.props.autoUpdate !== prevProps.autoUpdate) {
|
if (this.props.autoUpdate !== prevProps.autoUpdate) {
|
||||||
|
@ -886,8 +822,6 @@ class TopologyView extends React.Component {
|
||||||
|
|
||||||
const mapStateToProps = (state) => ({
|
const mapStateToProps = (state) => ({
|
||||||
currentOverlayId: state.evio.selectedOverlayId,
|
currentOverlayId: state.evio.selectedOverlayId,
|
||||||
//selectedElementType: state.evio.selectedElementType,
|
|
||||||
//selectedCyElementData: state.evio.selectedCyElementData,
|
|
||||||
cyElements: state.evio.cyElements,
|
cyElements: state.evio.cyElements,
|
||||||
currentView: state.view.current,
|
currentView: state.view.current,
|
||||||
selectedView: state.view.selected,
|
selectedView: state.view.selected,
|
||||||
|
@ -902,8 +836,6 @@ const mapDispatchToProps = {
|
||||||
setCurrentView,
|
setCurrentView,
|
||||||
setZoomValue,
|
setZoomValue,
|
||||||
setCyElements,
|
setCyElements,
|
||||||
//setSelectedElement,
|
|
||||||
//clearSelectedElement,
|
|
||||||
setRedrawGraph,
|
setRedrawGraph,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -181,6 +181,23 @@ h5 {
|
||||||
background-size: contain;
|
background-size: contain;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.collapse-header {
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 10px;
|
||||||
|
color: white;
|
||||||
|
background: #405b80;
|
||||||
|
border-radius: 5px;
|
||||||
|
transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out,
|
||||||
|
border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
|
||||||
|
}
|
||||||
|
.collapse-content {
|
||||||
|
padding: 8px;
|
||||||
|
color: white;
|
||||||
|
background: transparent;
|
||||||
|
border-radius: 5px;
|
||||||
|
transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out,
|
||||||
|
border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
|
||||||
|
}
|
||||||
.overlayBtn,
|
.overlayBtn,
|
||||||
.connectedNodeBtn,
|
.connectedNodeBtn,
|
||||||
.detailsNodeBtn,
|
.detailsNodeBtn,
|
||||||
|
|
Loading…
Reference in New Issue