From b9cb6551146f6981f77662295bac026532b70bf7 Mon Sep 17 00:00:00 2001 From: vkuchinov Date: Sun, 25 Aug 2019 17:32:21 +0300 Subject: [PATCH] Fixes Fixes for issues posted by Shay at VennDiagram component #412 [x] ResponsiveVennDiagram.js, VennDiagram.js [x] VennDiagram.css (rename) [x] ArcNode, CicularNode, Tooltip as .js and other minor issues --- .../components/pages/ZeroTrustReportPage.js | 203 ++++++++++-------- .../zerotrust/VennDiagram/ArcNode/index.js | 46 ---- .../zerotrust/venn-components/.DS_Store | Bin 0 -> 8196 bytes .../zerotrust/venn-components/ArcNode.js | 44 ++++ .../CircularNode.js} | 27 ++- .../venn-components/ResponsiveVennDiagram.js | 36 ++++ .../index.js => venn-components/Tooltip.js} | 0 .../utility.js => venn-components/Utility.js} | 0 .../VennDiagram.css} | 0 .../VennDiagram.js} | 184 +--------------- 10 files changed, 210 insertions(+), 330 deletions(-) mode change 100644 => 100755 monkey/monkey_island/cc/ui/src/components/pages/ZeroTrustReportPage.js delete mode 100644 monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/VennDiagram/ArcNode/index.js create mode 100644 monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/venn-components/.DS_Store create mode 100644 monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/venn-components/ArcNode.js rename monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/{VennDiagram/CircularNode/index.js => venn-components/CircularNode.js} (61%) create mode 100644 monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/venn-components/ResponsiveVennDiagram.js rename monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/{VennDiagram/Tooltip/index.js => venn-components/Tooltip.js} (100%) rename monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/{VennDiagram/utility.js => venn-components/Utility.js} (100%) rename monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/{VennDiagram/index.css => venn-components/VennDiagram.css} (100%) rename monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/{VennDiagram/index.js => venn-components/VennDiagram.js} (57%) diff --git a/monkey/monkey_island/cc/ui/src/components/pages/ZeroTrustReportPage.js b/monkey/monkey_island/cc/ui/src/components/pages/ZeroTrustReportPage.js old mode 100644 new mode 100755 index 2fe43c42e..e80af2366 --- a/monkey/monkey_island/cc/ui/src/components/pages/ZeroTrustReportPage.js +++ b/monkey/monkey_island/cc/ui/src/components/pages/ZeroTrustReportPage.js @@ -1,17 +1,64 @@ -import React, {Fragment} from 'react'; -import {Col, Grid, Row} from 'react-bootstrap'; +import React from 'react'; +import {Button, Col} from 'react-bootstrap'; import AuthComponent from '../AuthComponent'; import ReportHeader, {ReportTypes} from "../report-components/common/ReportHeader"; -import PillarsOverview from "../report-components/zerotrust/PillarOverview"; +import PillarGrades from "../report-components/zerotrust/PillarGrades"; +import PillarLabel from "../report-components/zerotrust/PillarLabel"; +import ResponsiveVennDiagram from "../report-components/zerotrust/venn-components/ResponsiveVennDiagram"; import FindingsTable from "../report-components/zerotrust/FindingsTable"; -import SinglePillarDirectivesStatus from "../report-components/zerotrust/SinglePillarDirectivesStatus"; -import MonkeysStillAliveWarning from "../report-components/common/MonkeysStillAliveWarning"; -import ReportLoader from "../report-components/common/ReportLoader"; -import MustRunMonkeyWarning from "../report-components/common/MustRunMonkeyWarning"; -import SecurityIssuesGlance from "../report-components/common/SecurityIssuesGlance"; -import StatusesToPillarsSummary from "../report-components/zerotrust/StatusesToPillarsSummary"; -import PrintReportButton from "../report-components/common/PrintReportButton"; -import {extractExecutionStatusFromServerResponse} from "../report-components/common/ExecutionStatus"; +import {SinglePillarRecommendationsStatus} from "../report-components/zerotrust/SinglePillarRecommendationsStatus"; + +let mockup = [ + { + "Conclusive": 4, + "Inconclusive": 0, + "Positive": 1, + "Unexecuted": 2, + "pillar": "Data" + }, + { + "Conclusive": 0, + "Inconclusive": 5, + "Positive": 0, + "Unexecuted": 2, + "pillar": "People" + }, + { + "Conclusive": 0, + "Inconclusive": 0, + "Positive": 6, + "Unexecuted": 3, + "pillar": "Networks" + }, + { + "Conclusive": 2, + "Inconclusive": 0, + "Positive": 1, + "Unexecuted": 1, + "pillar": "Devices" + }, + { + "Conclusive": 0, + "Inconclusive": 0, + "Positive": 0, + "Unexecuted": 0, + "pillar": "Workloads" + }, + { + "Conclusive": 0, + "Inconclusive": 2, + "Positive": 0, + "Unexecuted": 0, + "pillar": "Visibility & Analytics" + }, + { + "Conclusive": 0, + "Inconclusive": 0, + "Positive": 0, + "Unexecuted": 0, + "pillar": "Automation & Orchestration" + } +]; class ZeroTrustReportPageComponent extends AuthComponent { @@ -20,30 +67,16 @@ class ZeroTrustReportPageComponent extends AuthComponent { this.state = { allMonkeysAreDead: false, - runStarted: true + runStarted: false }; } - componentDidMount() { - this.updateMonkeysRunning().then(res => this.getZeroTrustReportFromServer(res)); - } - - updateMonkeysRunning = () => { - return this.authFetch('/api') - .then(res => res.json()) - .then(res => { - this.setState(extractExecutionStatusFromServerResponse(res)); - return res; - }); - }; - render() { - let content; - if (this.state.runStarted) { - content = this.generateReportContent(); - } else { - content = ; - } + let res; + // Todo move to componentDidMount + this.getZeroTrustReportFromServer(res); + + const content = this.generateReportContent(); return ( @@ -59,75 +92,63 @@ class ZeroTrustReportPageComponent extends AuthComponent { let content; if (this.stillLoadingDataFromServer()) { - content = ; + content = "Still empty"; } else { - content =
- {this.generateOverviewSection()} - {this.generateDirectivesSection()} - {this.generateFindingsSection()} + const pillarsSection =
+

Pillars Overview

+ +
; + + const recommendationsSection =

Recommendations Status

+ { + this.state.recommendations.map((recommendation) => + + ) + } +
; + + const findingSection =

Findings

+
; + + content =
+ {pillarsSection} + {recommendationsSection} + {findingSection}
; } return ( - -
- {print();}} /> +
+
+

{content} +
+
{JSON.stringify(this.state.pillars, undefined, 2)}
+
+ +
{JSON.stringify(this.state.recommendations, undefined, 2)}
+
+
{JSON.stringify(this.state.findings, undefined, 2)}
-
- {print();}} /> -
- +
) } - generateFindingsSection() { - return (
-

Findings

- -
); - } - - generateDirectivesSection() { - return (
-

Directives

- { - Object.keys(this.state.directives).map((pillar) => - - ) - } -
); - } - - generateOverviewSection() { - return (
-

Overview

- - - - - - - - - - - - -
); - } - stillLoadingDataFromServer() { - return typeof this.state.findings === "undefined" || typeof this.state.pillars === "undefined" || typeof this.state.directives === "undefined"; + return typeof this.state.findings === "undefined" || typeof this.state.pillars === "undefined" || typeof this.state.recommendations === "undefined"; + } + + print() { + alert("unimplemented"); } getZeroTrustReportFromServer() { @@ -139,11 +160,11 @@ class ZeroTrustReportPageComponent extends AuthComponent { findings: res }); }); - this.authFetch('/api/report/zero_trust/directives') + this.authFetch('/api/report/zero_trust/recommendations') .then(res => res.json()) .then(res => { this.setState({ - directives: res + recommendations: res }); }); this.authFetch('/api/report/zero_trust/pillars') @@ -154,14 +175,6 @@ class ZeroTrustReportPageComponent extends AuthComponent { }); }); } - - anyIssuesFound() { - const severe = function(finding) { - return (finding.status === "Conclusive" || finding.status === "Inconclusive"); - }; - - return this.state.findings.some(severe); - } } export default ZeroTrustReportPageComponent; diff --git a/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/VennDiagram/ArcNode/index.js b/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/VennDiagram/ArcNode/index.js deleted file mode 100644 index b9861a55e..000000000 --- a/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/VennDiagram/ArcNode/index.js +++ /dev/null @@ -1,46 +0,0 @@ -import React from 'react' -import PropTypes from 'prop-types'; -import * as d3 from 'd3' - -class ArcNode extends React.Component{ - - render() { - - let {prefix, ref, index, data} = this.props;; - - let arc = d3.arc().innerRadius(data.inner).outerRadius(data.outer).startAngle(0).endAngle(Math.PI * 2.0); - - return ( - - - - - - {data.label} - - - - - ) - - } - -} - -ArcNode.propTypes = { - - prefix: PropTypes.string, - index: PropTypes.number, - data: PropTypes.object - -} - -export default ArcNode; \ No newline at end of file diff --git a/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/venn-components/.DS_Store b/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/venn-components/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..344923cf9c56b32713b678e0b337a23ff212fa20 GIT binary patch literal 8196 zcmeHMT}&KR6h3F6<<5+h0V@S;%NlBhbc-x#!M3E!0<~0{R(JU;2;F6-Fgnc8o!O<7 zVu(#NCdL{yG4bcc#wUsPMHB6dFUH2G@rR@uV|>sTAB{#6pFH>8ffOhY`k*$QOYS{) z?m1`fIp6(e?%n|aFqt>v0963MsB)=m)ZCzOJ+JFZBp4|siR2I9g9X#s8E-mkud@yZ zLIgqtLIgqtLIgqt{tpPyp3Mu}VBeS8uniFi5x6B0;O~bhRW1{OT#!<{I;asx0FwL& zAPV*A93Xt6flLH)K}z9D_mrmx3|uidVxV*1n4SEh z!W=LmW!Q!Ygb1uhfImJZkOr6j?Ca0(Zk9BkWT$P*^P8HkVWg;d)8-P!RHl}ykESNw znUtUL^IkHO8|GIhGX7*X=%-!RUg>AD{gyd1rf=KP%>_ zjcV$ML9rZj4L*yZzsnS%*%j5aVXo=SnbaDLiQ)PNO-*||5jxaXFwH=0G8g+?!x#|K1r7qDFkbproG}1t3@ZF~nWbNm{YWPFij z(jE)q4FrBqos!iLCy|yut_jkP-jKB2ht(th5oy0Il}z1wM`i7YJqYezjF0BJ0IcyI(!Xh_Cu)sXe52DEv{=L0<3H6ovf* z4qk#qxB?%;r^LN$@B{n=zrdduL53BAciV9X)?z(2;2w-&Ber52G4KGk<6(Rdd+;c+ zun+rj5QlJ>SZE3sK87CpSil)#JidKsh* + + + + {data.label} + + + + + ) + + } + +} + +ArcNode.propTypes = { + + data: PropTypes.object + +} + +export default ArcNode; \ No newline at end of file diff --git a/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/VennDiagram/CircularNode/index.js b/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/venn-components/CircularNode.js similarity index 61% rename from monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/VennDiagram/CircularNode/index.js rename to monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/venn-components/CircularNode.js index a8caf5bb0..8d8df10bf 100644 --- a/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/VennDiagram/CircularNode/index.js +++ b/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/venn-components/CircularNode.js @@ -5,7 +5,7 @@ class CircularNode extends React.Component{ render() { - let {prefix, ref, index, data} = this.props; + let {prefix, index, data} = this.props; let tspans = data.label.split("|").map((d_, i_) =>{ @@ -21,23 +21,23 @@ class CircularNode extends React.Component{ }) let translate = 'translate(' + data.cx + ',' + data.cy + ')'; - + return ( - - - {tspans} - + /> + + {tspans} + ) @@ -48,7 +48,6 @@ class CircularNode extends React.Component{ CircularNode.propTypes = { - prefix: PropTypes.string, index: PropTypes.number, data: PropTypes.object diff --git a/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/venn-components/ResponsiveVennDiagram.js b/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/venn-components/ResponsiveVennDiagram.js new file mode 100644 index 000000000..d20abf94a --- /dev/null +++ b/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/venn-components/ResponsiveVennDiagram.js @@ -0,0 +1,36 @@ +import React from 'react' +import PropTypes from 'prop-types' +import Dimensions from 'react-dimensions' +import VennDiagram from './VennDiagram' + +const VENN_MIN_WIDTH = '300px'; + +class ResponsiveVennDiagram extends React.Component { + + constructor(props) { super(props); } + + render() { + + const {pillarsGrades} = this.props; + let childrenWidth = this.props.containerWidth, childrenHeight = this.props.containerHeight; + + if(childrenHeight === 0 || isNaN(childrenHeight)){ childrenHeight = childrenWidth; } + else{ childrenWidth = Math.min(childrenWidth, childrenHeight) } + + return ( + +
+ +
) + + } + +} + +ResponsiveVennDiagram.propTypes = { + + pillarsGrades: PropTypes.array + +} + +export default Dimensions()(ResponsiveVennDiagram); diff --git a/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/VennDiagram/Tooltip/index.js b/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/venn-components/Tooltip.js similarity index 100% rename from monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/VennDiagram/Tooltip/index.js rename to monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/venn-components/Tooltip.js diff --git a/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/VennDiagram/utility.js b/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/venn-components/Utility.js similarity index 100% rename from monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/VennDiagram/utility.js rename to monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/venn-components/Utility.js diff --git a/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/VennDiagram/index.css b/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/venn-components/VennDiagram.css similarity index 100% rename from monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/VennDiagram/index.css rename to monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/venn-components/VennDiagram.css diff --git a/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/VennDiagram/index.js b/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/venn-components/VennDiagram.js similarity index 57% rename from monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/VennDiagram/index.js rename to monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/venn-components/VennDiagram.js index 6a0b41356..0f154cdfe 100644 --- a/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/VennDiagram/index.js +++ b/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/venn-components/VennDiagram.js @@ -1,169 +1,10 @@ import React from 'react' -import PropTypes from 'prop-types'; -import Dimensions from 'react-dimensions' +import PropTypes from 'prop-types' import Tooltip from './Tooltip' import CircularNode from './CircularNode' import ArcNode from './ArcNode' -import { TypographicUtilities } from './utility.js' -import './index.css' - -/* - -TODO LIST - -UPDATED [21.08.2019] - -[-] SVG > ViewBox 0 0 512 512, so it would be responsive and scalable -[-] Add resize listener to ResponsiveVennDiagram wrapper -[-] I have noticed that you have PillarGrades at ZeroTrustReportPage, so how I can fetch the data out of it? - -UPDATED [20.08.2019] - -[x] I've seen that lots of D3 responsive examples are using 'wrapper' around the main component to - get parent container dimensions. And lister for resize. - - So, here it's Responsive(VennDiagram) - - If it doesn't work, I have another alternative: - - import React, { useRef, useEffect, useState, useLayoutEffect } from 'react' - - const ResponsiveVennDiagram = props => { - - const minWidth = 256; - const targetRef = useRef(); - const [dimensions, setDimensions] = useState({ width: 0, heigth: 0 }); - let movement_timer = null; - const RESET_TIMEOUT = 100; - - const checkForDimensionsUpdate = () => { - - if (targetRef.current) { - - setDimensions({ - - width: Math.min(targetRef.current.offsetWidth, targetRef.current.offsetHeight), - height: targetRef.current.offsetHeight - - }); - - } - }; - - useLayoutEffect(() => { checkForDimensionsUpdate(); }, []); - - window.addEventListener('resize', () => { clearInterval(movement_timer); movement_timer = setTimeout(checkForDimensionsUpdate, RESET_TIMEOUT); }); - - return ( - -
- -
- - ); - - }; - - ResponsiveVennDiagram.propTypes = { - - pillarsGrades: PropTypes.array - - } - - export default ResponsiveVennDiagram; - - While your diagram laout is squared, the VennDiaagram gets the min(width, height) - -[x] Colours have been updated. - -[x] String prototypes have been moved to '.utilities.js' - -[x] I have use the prefix 'vennDiagram' for all children elements to prevent naming conflicts with other components - DOM objects. - -[x] I have used PropTypes already a year ago on ThreeJS/ReactJS stack project. - -[!] External callback is still on my list, can you make a mockup for external function which have to get pillar variable? - -[!] Z-indices sorting on mouseover - Would be n my 21.08.2019 TODO list. With D3.JS it's an easy task, however would try do - make these z-soring without D3 framework. - -UPDATED [20.08.2019] - -[!] By now, there are three input props for VennDiagram component: - data, width and height. - -[-] Since layout has to be hardcoded, it's driven by this.layout object. - There're many ways of setting circles/arc positions, now I'm using the - stright-forward one. - - Usually, I am put all hardcoded params to external JSON file, i.e config.json. - Let me know if it's a good idea. - -[-] Could rearange z-indecies for nodes on hover, so highlighted node would have highest z-index. -[-] If you want callback on click even, please provide additional info what are you expecting to pass - through this. - -[!] I don't used to make lots of comments in my code, but treying to name everything in a way, - so third person could instantly get its job and concept. - - If it is not enoough just let me know. - -[!] I have tried to avoid using D3 so much, especially its mouse events, cause it creates a bunch - of listeners for every children DOM elements. I have tried to use raw SVG objects. - The ArcNode is the only component where I've to call d3.arc constrictor. - -[!] There are lots of discussion over different blogs an forums that ReactJS and D3.JS have a DOM - issue conflict, [could find lots of articels at medium.org about that, for example, - https://medium.com/@tibotiber/react-d3-js-balancing-performance-developer-experience-4da35f912484]. - - Since the current component has only a few DOM elements, I don't thing we would have any troubles, - but please keep in mind that I could tweak current version with react-faux-dom. - - Actually, by now, I'm using D3 only for math, for arc path calculations. - -[!] Don't mind about code spacings, it's just for me, the final code would be clear out of them. - -[-] On click, an EXTERNAL callback should be called with the pillar name as a parameter. That is to enable us to expand the click functionality in future without editing the internal implementation of the component. - -[-] planned, [x] done, [!] see comments - -@author Vladimir V KUCHINOV -@email helloworld@vkuchinov.co.uk - -*/ - -const VENN_MIN_WIDTH = '300px'; - -class ResponsiveVennDiagram extends React.Component { - - constructor(props) { super(props); } - render() { - - const {options, pillarsGrades} = this.props; - let childrenWidth = this.props.containerWidth, childrenHeight = this.props.containerHeight; - - if(childrenHeight === 0 || childrenHeight === NaN){ childrenHeight = childrenWidth; } - else{ childrenWidth = Math.min(childrenWidth, childrenHeight) } - - return ( - -
- -
) - - } - -} - -ResponsiveVennDiagram.propTypes = { - - pillarsGrades: PropTypes.array - -} - -export default Dimensions()(ResponsiveVennDiagram); +import { TypographicUtilities } from './Utility.js' +import './VennDiagram.css' class VennDiagram extends React.Component{ @@ -292,15 +133,6 @@ class VennDiagram extends React.Component{ } - relativeCoords (e) { - - let bounds = e.target.getBoundingClientRect(); - var x = e.clientX - bounds.left; - var y = e.clientY - bounds.top; - return {x: x, y: y}; - - } - parseData(){ let self = this; @@ -318,7 +150,7 @@ class VennDiagram extends React.Component{ for(let j = 0; j < self.rules.length; j++){ if(self.rules[j].f(d_)) { rule = j; break; }} self.setLayoutElement(rule, key, html, d_); - data.push(this.layout[key]) + data.push(this.layout[key]); }) @@ -361,7 +193,7 @@ class VennDiagram extends React.Component{