mirror of
https://github.com/openziti/zrok.git
synced 2025-02-22 05:01:01 +01:00
detail view scaffolding; selection management (#107)
This commit is contained in:
parent
dcf662ebff
commit
8d81eee3b0
@ -4,6 +4,7 @@ import Visualizer from "./visualizer/Visualizer";
|
||||
import Enable from "./modals/Enable";
|
||||
import Version from "./modals/Version";
|
||||
import * as metadata from "../api/metadata";
|
||||
import Detail from "./Detail";
|
||||
|
||||
const Console = (props) => {
|
||||
const [showEnableModal, setShowEnableModal] = useState(false);
|
||||
@ -38,7 +39,10 @@ const Console = (props) => {
|
||||
mounted = false;
|
||||
clearInterval(interval);
|
||||
}
|
||||
}, [])
|
||||
}, []);
|
||||
|
||||
const defaultSelection = {id: props.user.token, type: "account"};
|
||||
const [selection, setSelection] = useState(defaultSelection);
|
||||
|
||||
return (
|
||||
<Container fluid={"xl"}>
|
||||
@ -60,7 +64,14 @@ const Console = (props) => {
|
||||
</Navbar.Collapse>
|
||||
</Container>
|
||||
</Navbar>
|
||||
<Visualizer user={props.user} overview={overview} />
|
||||
<Visualizer
|
||||
user={props.user}
|
||||
overview={overview}
|
||||
defaultSelection={defaultSelection}
|
||||
selection={selection}
|
||||
setSelection={setSelection}
|
||||
/>
|
||||
<Detail selection={selection} />
|
||||
<Enable show={showEnableModal} onHide={closeEnableModal} token={props.user.token} />
|
||||
<Version show={showVersionModal} onHide={closeVersionModal} />
|
||||
</Container>
|
||||
|
9
ui/src/console/Detail.js
Normal file
9
ui/src/console/Detail.js
Normal file
@ -0,0 +1,9 @@
|
||||
const Detail = (props) => {
|
||||
return (
|
||||
<div className={"detail-container"}>
|
||||
<h1>{props.selection.id} ({props.selection.type})</h1>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Detail;
|
@ -16,12 +16,11 @@ const Network = (props) => {
|
||||
}, []);
|
||||
|
||||
const paintNode = (node, ctx) => {
|
||||
let nodeColor = "#555";
|
||||
let nodeColor = "#636363";
|
||||
let textColor = "white";
|
||||
switch(node.type) {
|
||||
case "environment":
|
||||
nodeColor = "#777";
|
||||
textColor = "black";
|
||||
nodeColor = "#444";
|
||||
break;
|
||||
case "service":
|
||||
nodeColor = "#291A66";
|
||||
@ -38,10 +37,15 @@ const Network = (props) => {
|
||||
roundRect(ctx, node.x - (nodeWidth / 2), node.y - 7, nodeWidth, 14, 1.25);
|
||||
ctx.fill();
|
||||
|
||||
switch(node.type) {
|
||||
case "service":
|
||||
ctx.strokeStyle = "#433482";
|
||||
ctx.stroke();
|
||||
if(node.selected) {
|
||||
ctx.strokeStyle = "#c4bdde";
|
||||
ctx.stroke();
|
||||
} else {
|
||||
switch(node.type) {
|
||||
case "service":
|
||||
ctx.strokeStyle = "#433482";
|
||||
ctx.stroke();
|
||||
}
|
||||
}
|
||||
|
||||
ctx.fillStyle = textColor;
|
||||
@ -49,7 +53,7 @@ const Network = (props) => {
|
||||
}
|
||||
|
||||
const nodeClicked = (node) => {
|
||||
console.log("node clicked", node.label);
|
||||
props.setSelection({id: node.id, type: node.type});
|
||||
}
|
||||
|
||||
return (
|
||||
|
@ -2,13 +2,26 @@ import React, {useEffect, useState} from "react";
|
||||
import {Button} from "react-bootstrap";
|
||||
import Network from "./Network";
|
||||
import {mergeGraph} from "./graph";
|
||||
import {isSelectionGone, markSelected} from "./selection";
|
||||
|
||||
const Visualizer = (props) => {
|
||||
const [networkGraph, setNetworkGraph] = useState({nodes: [], links: []});
|
||||
|
||||
useEffect(() => {
|
||||
setNetworkGraph(mergeGraph(networkGraph, props.user, props.overview));
|
||||
}, [props]);
|
||||
|
||||
if(isSelectionGone(networkGraph, props.selection)) {
|
||||
// if the selection is no longer in the network graph...
|
||||
console.log("resetting selection", props.selection);
|
||||
props.setSelection(props.defaultSelection);
|
||||
}
|
||||
}, [props.overview]);
|
||||
|
||||
markSelected(networkGraph, props.selection);
|
||||
|
||||
useEffect(() => {
|
||||
markSelected(networkGraph, props.selection);
|
||||
}, [props.selection]);
|
||||
|
||||
// fgRef to access force graph controls from this component
|
||||
let fgRef = () => { };
|
||||
@ -26,6 +39,7 @@ const Visualizer = (props) => {
|
||||
<Network
|
||||
networkGraph={networkGraph}
|
||||
setRef={setFgRef}
|
||||
setSelection={props.setSelection}
|
||||
/>
|
||||
<div className={"visualizer-controls"}>
|
||||
<Button variant={"secondary"} size={"sm"} onClick={centerFocus}>Zoom to Fit</Button>
|
||||
|
8
ui/src/console/visualizer/selection.js
Normal file
8
ui/src/console/visualizer/selection.js
Normal file
@ -0,0 +1,8 @@
|
||||
export const isSelectionGone = (networkGraph, selection) => {
|
||||
// the selection is gone if the selection is not found in the network graph
|
||||
return !networkGraph.nodes.find(node => selection.id === node.id);
|
||||
}
|
||||
|
||||
export const markSelected = (networkGraph, selection) => {
|
||||
networkGraph.nodes.forEach(node => { node.selected = node.id === selection.id; });
|
||||
}
|
@ -14,6 +14,14 @@ code, pre {
|
||||
padding: 15px 50px 20px;
|
||||
}
|
||||
|
||||
.header-title {
|
||||
font-family: 'Russo One', sans-serif;
|
||||
font-size: 3em;
|
||||
margin-left: 0.53em;
|
||||
vertical-align: center;
|
||||
line-height: 1.7;
|
||||
}
|
||||
|
||||
.visualizer-container {
|
||||
padding: 10px;
|
||||
background: #3b2693;
|
||||
@ -25,12 +33,8 @@ code, pre {
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.header-title {
|
||||
font-family: 'Russo One', sans-serif;
|
||||
font-size: 3em;
|
||||
margin-left: 0.53em;
|
||||
vertical-align: center;
|
||||
line-height: 1.7;
|
||||
.detail-container {
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
.btn-close {
|
||||
|
Loading…
Reference in New Issue
Block a user