detail view scaffolding; selection management (#107)

This commit is contained in:
Michael Quigley 2022-12-22 12:32:40 -05:00
parent dcf662ebff
commit 8d81eee3b0
No known key found for this signature in database
GPG Key ID: 9B60314A9DD20A62
6 changed files with 67 additions and 17 deletions

View File

@ -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
View 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;

View File

@ -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 (

View File

@ -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>

View 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; });
}

View File

@ -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 {