From 7425bf1bbd0c389f90958a651cd0318d570a3ae9 Mon Sep 17 00:00:00 2001 From: VakarisZ Date: Thu, 28 Oct 2021 14:37:11 +0300 Subject: [PATCH] UI: refactor TelemetryLog component out of MapPage and migrate it to hook with typescript --- .../cc/ui/src/components/map/TelemetryLog.tsx | 96 +++++++++++++++++++ .../cc/ui/src/components/pages/MapPage.js | 89 +---------------- 2 files changed, 100 insertions(+), 85 deletions(-) create mode 100644 monkey/monkey_island/cc/ui/src/components/map/TelemetryLog.tsx diff --git a/monkey/monkey_island/cc/ui/src/components/map/TelemetryLog.tsx b/monkey/monkey_island/cc/ui/src/components/map/TelemetryLog.tsx new file mode 100644 index 000000000..f247bbf91 --- /dev/null +++ b/monkey/monkey_island/cc/ui/src/components/map/TelemetryLog.tsx @@ -0,0 +1,96 @@ +import React, {useEffect, useRef, useState} from 'react'; +import AuthComponent from '../AuthComponent'; + + +const authComponent = new AuthComponent({}); + +const TelemetryLog = (props: { onStatusChange: Function }) => { + + let [telemetryUpdateInProgress, setTelemetryUpdateInProgress] = useState(false); + let [telemetry, setTelemetry] = useState([]); + let [lastTelemetryTimestamp, setLastTelemetryTimestamp] = useState(null); + let [isScrolledUp, setIsScrolledUp] = useState(false); + let [telemetryLines, setTelemetryLines] = useState(0); + let [telemetryCurrentLine, setTelemetryCurrentLine] = useState(0); + + let scrollTop = 0; + const telemetryConsole = useRef(null); + + useEffect(() => { + const interval = setInterval(updateTelemetryFromServer, 5000); + return function cleanup() { + clearInterval(interval); + }; + }, []); + + function updateTelemetryFromServer() { + if (telemetryUpdateInProgress) { + return + } + setTelemetryUpdateInProgress(true); + authComponent.authFetch('/api/telemetry-feed?timestamp=' + lastTelemetryTimestamp) + .then(res => res.json()) + .then(res => { + if ('telemetries' in res) { + let newTelem = telemetry.concat(res['telemetries']); + setTelemetry(newTelem); + setLastTelemetryTimestamp(res['timestamp']); + setTelemetryUpdateInProgress(false); + props.onStatusChange(); + + let telemConsoleRef = telemetryConsole.current; + if (!isScrolledUp) { + telemConsoleRef.scrollTop = telemConsoleRef.scrollHeight - telemConsoleRef.clientHeight; + scrollTop = telemConsoleRef.scrollTop; + } + } + }); + } + + function handleScroll(e) { + let element = e.target; + + let telemetryStyle = window.getComputedStyle(element); + let telemetryLineHeight = parseInt((telemetryStyle.lineHeight).replace('px', '')); + + setIsScrolledUp((element.scrollTop < scrollTop)); + setTelemetryCurrentLine(Math.trunc(element.scrollTop / telemetryLineHeight) + 1); + setTelemetryLines(Math.trunc(element.scrollHeight / telemetryLineHeight)); + } + + function renderTelemetryConsole() { + return ( +
+ { + telemetry.map(renderTelemetryEntry) + } +
+ ); + } + + function renderTelemetryEntry(telemetry) { + return ( +
+ {telemetry.timestamp} + {telemetry.hostname}: + {telemetry.brief} +
+ ); + } + + function renderTelemetryLineCount() { + return ( +
+ [{telemetryCurrentLine}/{telemetryLines}] +
+ ); + } + + return ( + <> + {renderTelemetryLineCount()} + {renderTelemetryConsole()} + ); +} + +export default TelemetryLog; diff --git a/monkey/monkey_island/cc/ui/src/components/pages/MapPage.js b/monkey/monkey_island/cc/ui/src/components/pages/MapPage.js index da11c7ed6..6026cebb6 100644 --- a/monkey/monkey_island/cc/ui/src/components/pages/MapPage.js +++ b/monkey/monkey_island/cc/ui/src/components/pages/MapPage.js @@ -10,6 +10,7 @@ import {getOptions, edgeGroupToColor} from 'components/map/MapOptions'; import AuthComponent from '../AuthComponent'; import '../../styles/components/Map.scss'; import {faInfoCircle} from '@fortawesome/free-solid-svg-icons/faInfoCircle'; +import TelemetryLog from '../map/TelemetryLog'; class MapPageComponent extends AuthComponent { constructor(props) { @@ -20,17 +21,8 @@ class MapPageComponent extends AuthComponent { selected: null, selectedType: null, killPressed: false, - showKillDialog: false, - telemetry: [], - telemetryLastTimestamp: null, - isScrolledUp: false, - telemetryLines: 0, - telemetryCurrentLine: 0, - telemetryUpdateInProgress: false + showKillDialog: false }; - this.telemConsole = React.createRef(); - this.handleScroll = this.handleScroll.bind(this); - this.scrollTop = 0; } events = { @@ -40,7 +32,7 @@ class MapPageComponent extends AuthComponent { componentDidMount() { this.getNodeStateListFromServer(); this.updateMapFromServer(); - this.interval = setInterval(this.timedEvents, 5000); + this.interval = setInterval(this.updateMapFromServer, 5000); } componentWillUnmount() { @@ -55,11 +47,6 @@ class MapPageComponent extends AuthComponent { }); }; - timedEvents = () => { - this.updateMapFromServer(); - this.updateTelemetryFromServer(); - }; - updateMapFromServer = () => { this.authFetch('/api/netmap') .then(res => res.json()) @@ -74,33 +61,6 @@ class MapPageComponent extends AuthComponent { }); }; - updateTelemetryFromServer = () => { - if (this.state.telemetryUpdateInProgress) { - return - } - this.setState({telemetryUpdateInProgress: true}); - this.authFetch('/api/telemetry-feed?timestamp=' + this.state.telemetryLastTimestamp) - .then(res => res.json()) - .then(res => { - if ('telemetries' in res) { - let newTelem = this.state.telemetry.concat(res['telemetries']); - this.setState( - { - telemetry: newTelem, - telemetryLastTimestamp: res['timestamp'], - telemetryUpdateInProgress: false - }); - this.props.onStatusChange(); - - let telemConsoleRef = this.telemConsole.current; - if (!this.state.isScrolledUp) { - telemConsoleRef.scrollTop = telemConsoleRef.scrollHeight - telemConsoleRef.clientHeight; - this.scrollTop = telemConsoleRef.scrollTop; - } - } - }); - }; - selectionChanged(event) { if (event.nodes.length === 1) { this.authFetch('/api/netmap/node?id=' + event.nodes[0]) @@ -157,46 +117,6 @@ class MapPageComponent extends AuthComponent { ) }; - renderTelemetryEntry(telemetry) { - return ( -
- {telemetry.timestamp} - {telemetry.hostname}: - {telemetry.brief} -
- ); - } - - handleScroll(e) { - let element = e.target; - - let telemetryStyle = window.getComputedStyle(element); - let telemetryLineHeight = parseInt((telemetryStyle.lineHeight).replace('px', '')); - - this.setState({ - isScrolledUp: (element.scrollTop < this.scrollTop), - telemetryCurrentLine: Math.trunc(element.scrollTop / telemetryLineHeight) + 1, - telemetryLines: Math.trunc(element.scrollHeight / telemetryLineHeight) - }); - } - - renderTelemetryConsole() { - return ( -
- { - this.state.telemetry.map(this.renderTelemetryEntry) - } -
- ); - } - - renderTelemetryLineCount() { - return ( -
- [{this.state.telemetryCurrentLine}/{this.state.telemetryLines}] -
- ); - } render() { return ( @@ -220,10 +140,9 @@ class MapPageComponent extends AuthComponent { Island Communication
- {this.renderTelemetryLineCount()} - {this.renderTelemetryConsole()} +