diff --git a/public/pages/Correlations/components/CorrelationGraph.tsx b/public/pages/Correlations/components/CorrelationGraph.tsx index 238cd8d82..ec6a836ee 100644 --- a/public/pages/Correlations/components/CorrelationGraph.tsx +++ b/public/pages/Correlations/components/CorrelationGraph.tsx @@ -4,17 +4,41 @@ */ import React from 'react'; -import Graph from 'react-graph-vis'; +import Graph, { Edge, GraphEvents, Network, Node, Options } from 'react-graph-vis'; +import 'vis-network/dist/dist/vis-network.min.css'; +import { EuiLoadingChart } from '@elastic/eui'; -export const CorrelationGraph = ({ graph: { nodes, edges }, options, events }) => { - return ( +interface CorrelationGraphProps { + loadingData: boolean; + graph: { + nodes: Node[]; + edges: Edge[]; + }; + options: Options; + events: GraphEvents; + getNetwork: (network: Network) => void; +} + +export const CorrelationGraph: React.FC = ({ + graph: { nodes, edges }, + options, + events, + loadingData, + getNetwork, +}) => { + return loadingData ? ( +
+ +
+ ) : ( ); }; diff --git a/public/pages/Correlations/containers/CorrelationsContainer.tsx b/public/pages/Correlations/containers/CorrelationsContainer.tsx index 554de6f9d..a4b93f7ea 100644 --- a/public/pages/Correlations/containers/CorrelationsContainer.tsx +++ b/public/pages/Correlations/containers/CorrelationsContainer.tsx @@ -10,7 +10,9 @@ import { defaultSeverityFilterItemOptions, emptyGraphData, getAbbrFromLogType, + getLabelFromLogType, getSeverityColor, + getSeverityLabel, graphRenderOptions, } from '../utils/constants'; import { @@ -29,6 +31,7 @@ import { EuiText, EuiEmptyPrompt, EuiButton, + EuiBadge, } from '@elastic/eui'; import { CorrelationsExperimentalBanner } from '../components/ExperimentalBanner'; import { FilterItem, FilterGroup } from '../components/FilterGroup'; @@ -45,6 +48,8 @@ import { DataStore } from '../../../store/DataStore'; import { FindingItemType } from '../../Findings/containers/Findings/Findings'; import datemath from '@elastic/datemath'; import { ruleSeverity } from '../../Rules/utils/constants'; +import { renderToStaticMarkup } from 'react-dom/server'; +import { Network } from 'react-graph-vis'; interface CorrelationsProps extends RouteComponentProps< @@ -68,10 +73,13 @@ interface CorrelationsState { specificFindingInfo?: SpecificFindingCorrelations; logTypeFilterOptions: FilterItem[]; severityFilterOptions: FilterItem[]; + loadingGraphData: boolean; } export class Correlations extends React.Component { static contextType = CoreServicesContext; + private correlationGraphNetwork?: Network; + constructor(props: CorrelationsProps) { super(props); this.state = { @@ -80,6 +88,7 @@ export class Correlations extends React.Component { return this.shouldShowFinding(corr.finding1) && this.shouldShowFinding(corr.finding2); }); @@ -256,6 +267,7 @@ export class Correlations extends React.Component { - const tooltip = document.createElement('div'); + private createNodeTooltip = ({ detectionRule, timestamp, logType }: CorrelationFinding) => { + const tooltipContent = ( +
+ + + + {getSeverityLabel(detectionRule.severity)} + + + + {getLabelFromLogType(logType)} + + + + {timestamp} +
+ ); - function createRow(text: string) { - const row = document.createElement('p'); - row.innerText = text; - row.style.padding = '5px'; - return row; - } + const tooltipContentHTML = renderToStaticMarkup(tooltipContent); - tooltip.appendChild(createRow(`Log type: ${finding.logType}`)); - tooltip.appendChild(createRow(finding.timestamp)); + const tooltip = document.createElement('div'); + tooltip.innerHTML = tooltipContentHTML; - return tooltip; + return tooltip.firstElementChild; }; private onTimeChange = ({ start, end }: { start: string; end: string }) => { @@ -324,6 +347,7 @@ export class Correlations extends React.Component { @@ -339,6 +363,36 @@ export class Correlations extends React.Component { + this.correlationGraphNetwork = network; + }; + + renderCorrelationsGraph(loadingData: boolean) { + return this.state.graphData.graph.nodes.length > 0 || loadingData ? ( + + ) : ( + +

No correlations found

+ + } + body={

There are no correlated findings in the system.

} + actions={[ + + Create correlation rule + , + ]} + /> + ); + } + render() { const findingCardsData = this.state.specificFindingInfo; @@ -476,31 +530,7 @@ export class Correlations extends React.Component - {this.state.graphData.graph.nodes.length > 0 ? ( - - ) : ( - -

No correlations found

- - } - body={

There are no correlated findings in the system.

} - actions={[ - - Create correlation rule - , - ]} - /> - )} + {this.renderCorrelationsGraph(this.state.loadingGraphData)} diff --git a/public/pages/Correlations/utils/constants.tsx b/public/pages/Correlations/utils/constants.tsx index 10ae382a1..e51b09aa9 100644 --- a/public/pages/Correlations/utils/constants.tsx +++ b/public/pages/Correlations/utils/constants.tsx @@ -43,6 +43,7 @@ export const graphRenderOptions = { dragNodes: false, multiselect: true, tooltipDelay: 50, + hover: true, }, };