From 898efcbfec8aefd2be9bb62790ffd4d0aa916cc7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Ricks?= Date: Mon, 1 Oct 2018 15:02:49 +0200 Subject: [PATCH 01/25] Extract rendering of dashboard display icons into own component --- gsa/CMakeLists.txt | 1 + .../dashboard/display/datadisplay.js | 31 +++----- .../dashboard/display/datadisplayicons.js | 75 +++++++++++++++++++ 3 files changed, 85 insertions(+), 22 deletions(-) create mode 100644 gsa/src/web/components/dashboard/display/datadisplayicons.js diff --git a/gsa/CMakeLists.txt b/gsa/CMakeLists.txt index 701a7dd01c..d9f23ddffd 100644 --- a/gsa/CMakeLists.txt +++ b/gsa/CMakeLists.txt @@ -219,6 +219,7 @@ set (GSA_JS_SRC_FILES ${GSA_SRC_DIR}/src/web/components/dashboard/display/cvss/cvsstabledisplay.js ${GSA_SRC_DIR}/src/web/components/dashboard/display/cvss/cvsstransform.js ${GSA_SRC_DIR}/src/web/components/dashboard/display/datadisplay.js + ${GSA_SRC_DIR}/src/web/components/dashboard/display/datadisplayicons.js ${GSA_SRC_DIR}/src/web/components/dashboard/display/datatable.js ${GSA_SRC_DIR}/src/web/components/dashboard/display/datatabledisplay.js ${GSA_SRC_DIR}/src/web/components/dashboard/display/display.js diff --git a/gsa/src/web/components/dashboard/display/datadisplay.js b/gsa/src/web/components/dashboard/display/datadisplay.js index 0669f39fdc..a08312ebd5 100644 --- a/gsa/src/web/components/dashboard/display/datadisplay.js +++ b/gsa/src/web/components/dashboard/display/datadisplay.js @@ -32,7 +32,6 @@ import _ from 'gmp/locale'; import {isDefined} from 'gmp/utils/identity'; import {excludeObjectProps} from 'gmp/utils/object'; -import Icon from 'web/components/icon/icon'; import IconDivider from 'web/components/layout/icondivider'; import Layout from 'web/components/layout/layout'; @@ -44,6 +43,7 @@ import Theme from 'web/utils/theme'; import Display, { DISPLAY_HEADER_HEIGHT, DISPLAY_BORDER_WIDTH, } from './display'; +import DataDisplayIcons from './datadisplayicons'; export const MENU_PLACEHOLDER_WIDTH = 26; @@ -320,27 +320,14 @@ class DataDisplay extends React.Component { } - {showFilterSelection && - - } - {hasSvg && - - } - {showCsvDownload && - - } + {showFilterString && diff --git a/gsa/src/web/components/dashboard/display/datadisplayicons.js b/gsa/src/web/components/dashboard/display/datadisplayicons.js new file mode 100644 index 0000000000..9b8a7858d2 --- /dev/null +++ b/gsa/src/web/components/dashboard/display/datadisplayicons.js @@ -0,0 +1,75 @@ +/* Greenbone Security Assistant + * + * Authors: + * Björn Ricks + * + * Copyright: + * Copyright (C) 2018 Greenbone Networks GmbH + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + */ +import React from 'react'; + +import {_} from 'gmp/locale/lang'; + +import Icon from 'web/components/icon/icon'; + +import PropTypes from 'web/utils/proptypes'; + +const DataDisplayIcons = ({ + showCsvDownload = true, + showSvgDownload = true, + showFilterSelection = true, + onDownloadCsvClick, + onDownloadSvgClick, + onSelectFilterClick, +}) => ( + + {showFilterSelection && + + } + {showSvgDownload && + + } + {showCsvDownload && + + } + +); + +DataDisplayIcons.propTypes = { + showCsvDownload: PropTypes.bool, + showFilterSelection: PropTypes.bool, + showSvgDownload: PropTypes.bool, + onDownloadCsvClick: PropTypes.func, + onDownloadSvgClick: PropTypes.func, + onSelectFilterClick: PropTypes.func, +}; + +export default DataDisplayIcons; + +// vim: set ts=2 sw=2 tw=80: From ba002c3b9424459b34169bf9846032a4f85627bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Ricks?= Date: Mon, 1 Oct 2018 16:06:00 +0200 Subject: [PATCH 02/25] Resort methods in DataDisplay Move react state methods up. --- .../dashboard/display/datadisplay.js | 50 +++++++++---------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/gsa/src/web/components/dashboard/display/datadisplay.js b/gsa/src/web/components/dashboard/display/datadisplay.js index a08312ebd5..7add02e22c 100644 --- a/gsa/src/web/components/dashboard/display/datadisplay.js +++ b/gsa/src/web/components/dashboard/display/datadisplay.js @@ -157,12 +157,16 @@ class DataDisplay extends React.Component { dataTransform(data, tprops) : data; } - hasFilterChanged(nextProps) { - if (isDefined(this.props.filter)) { - return this.props.filter.equals(nextProps.filter); - } + componentWillUnmount() { + this.cleanupDownloadSvg(); + } - return isDefined(nextProps.filter); + componentDidUpdate() { + this.setHasSvg(); + } + + componentDidMount() { + this.setHasSvg(); } shouldComponentUpdate(nextProps, nextState) { @@ -174,6 +178,22 @@ class DataDisplay extends React.Component { this.hasFilterChanged(nextProps); } + hasFilterChanged(nextProps) { + if (isDefined(this.props.filter)) { + return this.props.filter.equals(nextProps.filter); + } + + return isDefined(nextProps.filter); + } + + setHasSvg() { + this.setState(prevState => { + const {current: svg} = this.svgRef; + const hasSvg = svg !== null; + return prevState.hasSvg === hasSvg ? null : {hasSvg}; + }); + } + createSvgUrl() { const {current: svg} = this.svgRef; const {height, width} = this.props; @@ -240,26 +260,6 @@ class DataDisplay extends React.Component { download.click(); } - componentWillUnmount() { - this.cleanupDownloadSvg(); - } - - setHasSvg() { - this.setState(prevState => { - const {current: svg} = this.svgRef; - const hasSvg = svg !== null; - return prevState.hasSvg === hasSvg ? null : {hasSvg}; - }); - } - - componentDidUpdate() { - this.setHasSvg(); - } - - componentDidMount() { - this.setHasSvg(); - } - render() { const {data: transformedData, title} = this.state; let { From 3bdb9d71a4f933cfda05b98c5bfa0f15995da884 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Ricks?= Date: Mon, 1 Oct 2018 16:10:01 +0200 Subject: [PATCH 03/25] No need to put hasSvg into the DataDisplay state hasSvg can always be derived in render. --- .../dashboard/display/datadisplay.js | 22 +++---------------- 1 file changed, 3 insertions(+), 19 deletions(-) diff --git a/gsa/src/web/components/dashboard/display/datadisplay.js b/gsa/src/web/components/dashboard/display/datadisplay.js index 7add02e22c..f14ac8aec4 100644 --- a/gsa/src/web/components/dashboard/display/datadisplay.js +++ b/gsa/src/web/components/dashboard/display/datadisplay.js @@ -161,19 +161,10 @@ class DataDisplay extends React.Component { this.cleanupDownloadSvg(); } - componentDidUpdate() { - this.setHasSvg(); - } - - componentDidMount() { - this.setHasSvg(); - } - shouldComponentUpdate(nextProps, nextState) { return nextProps.height !== this.props.height || nextProps.width !== this.props.width || nextState.data !== this.state.data || - nextState.hasSvg !== this.state.hasSvg || nextProps.showFilterString !== this.props.showFilterString || this.hasFilterChanged(nextProps); } @@ -186,14 +177,6 @@ class DataDisplay extends React.Component { return isDefined(nextProps.filter); } - setHasSvg() { - this.setState(prevState => { - const {current: svg} = this.svgRef; - const hasSvg = svg !== null; - return prevState.hasSvg === hasSvg ? null : {hasSvg}; - }); - } - createSvgUrl() { const {current: svg} = this.svgRef; const {height, width} = this.props; @@ -276,13 +259,12 @@ class DataDisplay extends React.Component { dataTitles, dataRow, filter, + icons, onSelectFilterClick, onRemoveClick, ...props } = this.props; - const {hasSvg = false} = this.state; - height = height - DISPLAY_HEADER_HEIGHT; width = width - DISPLAY_BORDER_WIDTH; @@ -297,6 +279,8 @@ class DataDisplay extends React.Component { } const showContent = height > 0 && width > 0; // > 0 also checks for null, undefined and null + const {current: svg} = this.svgRef; + const hasSvg = !!svg; return ( Date: Tue, 2 Oct 2018 09:37:32 +0200 Subject: [PATCH 04/25] Allow to toggle the Legend in children of DataDisplay Add icon to toggle displaying the legend of charts. --- .../dashboard/display/datadisplay.js | 18 +++++++++++++++++- .../dashboard/display/datadisplayicons.js | 11 +++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/gsa/src/web/components/dashboard/display/datadisplay.js b/gsa/src/web/components/dashboard/display/datadisplay.js index f14ac8aec4..9054aa4cb3 100644 --- a/gsa/src/web/components/dashboard/display/datadisplay.js +++ b/gsa/src/web/components/dashboard/display/datadisplay.js @@ -125,10 +125,12 @@ class DataDisplay extends React.Component { data, originalData: this.props.data, title: this.props.title({data, id: this.props.id}), + showLegend: true, }; this.handleDownloadSvg = this.handleDownloadSvg.bind(this); this.handleDownloadCsv = this.handleDownloadCsv.bind(this); + this.handleToggleLegend = this.handleToggleLegend.bind(this); } static getDerivedStateFromProps(nextProps, prevState) { @@ -165,6 +167,7 @@ class DataDisplay extends React.Component { return nextProps.height !== this.props.height || nextProps.width !== this.props.width || nextState.data !== this.state.data || + nextState.showLegend !== this.state.showLegend || nextProps.showFilterString !== this.props.showFilterString || this.hasFilterChanged(nextProps); } @@ -243,8 +246,16 @@ class DataDisplay extends React.Component { download.click(); } + handleToggleLegend() { + this.setState(({showLegend}) => ({showLegend: !showLegend})); + } + render() { - const {data: transformedData, title} = this.state; + const { + data: transformedData, + title, + showLegend, + } = this.state; let { data: originalData, height, @@ -260,6 +271,7 @@ class DataDisplay extends React.Component { dataRow, filter, icons, + showToggleLegend, onSelectFilterClick, onRemoveClick, ...props @@ -299,6 +311,7 @@ class DataDisplay extends React.Component { width, height, svgRef: this.svgRef, + showLegend, })} } @@ -308,9 +321,11 @@ class DataDisplay extends React.Component { showCsvDownload={showCsvDownload} showFilterSelection={showFilterSelection} showSvgDownload={hasSvg} + showToggleLegend={showToggleLegend} onDownloadCsvClick={this.handleDownloadCsv} onDownloadSvgClick={this.handleDownloadSvg} onSelectFilterClick={onSelectFilterClick} + onToggleLegendClick={this.handleToggleLegend} /> @@ -342,6 +357,7 @@ DataDisplay.propTypes = { isLoading: PropTypes.bool, showFilterSelection: PropTypes.bool, showFilterString: PropTypes.bool, + showToggleLegend: PropTypes.bool, title: PropTypes.func.isRequired, width: PropTypes.number.isRequired, onRemoveClick: PropTypes.func.isRequired, diff --git a/gsa/src/web/components/dashboard/display/datadisplayicons.js b/gsa/src/web/components/dashboard/display/datadisplayicons.js index 9b8a7858d2..b10c544450 100644 --- a/gsa/src/web/components/dashboard/display/datadisplayicons.js +++ b/gsa/src/web/components/dashboard/display/datadisplayicons.js @@ -32,9 +32,11 @@ const DataDisplayIcons = ({ showCsvDownload = true, showSvgDownload = true, showFilterSelection = true, + showToggleLegend = true, onDownloadCsvClick, onDownloadSvgClick, onSelectFilterClick, + onToggleLegendClick, }) => ( {showFilterSelection && @@ -58,6 +60,13 @@ const DataDisplayIcons = ({ onClick={onDownloadCsvClick} /> } + {showToggleLegend && + + } ); @@ -65,9 +74,11 @@ DataDisplayIcons.propTypes = { showCsvDownload: PropTypes.bool, showFilterSelection: PropTypes.bool, showSvgDownload: PropTypes.bool, + showToggleLegend: PropTypes.bool, onDownloadCsvClick: PropTypes.func, onDownloadSvgClick: PropTypes.func, onSelectFilterClick: PropTypes.func, + onToggleLegendClick: PropTypes.func, }; export default DataDisplayIcons; From 442339223228354408b17efe4e74bbd6ab0c1bf5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Ricks?= Date: Tue, 2 Oct 2018 09:42:36 +0200 Subject: [PATCH 05/25] Use DataDisplay icons prop as render props Allow to override the icon prop of DataDisplay to render different icons for a chart. --- .../dashboard/display/datadisplay.js | 25 +++++++++++-------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/gsa/src/web/components/dashboard/display/datadisplay.js b/gsa/src/web/components/dashboard/display/datadisplay.js index 9054aa4cb3..33d2cb1b41 100644 --- a/gsa/src/web/components/dashboard/display/datadisplay.js +++ b/gsa/src/web/components/dashboard/display/datadisplay.js @@ -112,6 +112,8 @@ const DisplayBox = styled.div` const escapeCsv = value => '"' + `${value}`.replace('"', '""') + '"'; +const renderIcons = props => ; + class DataDisplay extends React.Component { constructor(...args) { @@ -270,7 +272,7 @@ class DataDisplay extends React.Component { dataTitles, dataRow, filter, - icons, + icons = renderIcons, showToggleLegend, onSelectFilterClick, onRemoveClick, @@ -317,16 +319,16 @@ class DataDisplay extends React.Component { } - + {icons && icons({ + showFilterSelection, + showCsvDownload, + showSvgDownload: hasSvg, + showToggleLegend, + onDownloadCsvClick: this.handleDownloadSvg, + onDownloadSvgClick: this.handleDownloadSvg, + onToggleLegendClick: this.handleToggleLegend, + onSelectFilterClick, + })} {showFilterString && @@ -353,6 +355,7 @@ DataDisplay.propTypes = { dataTransform: PropTypes.func, filter: PropTypes.filter, height: PropTypes.number.isRequired, + icons: PropTypes.func, id: PropTypes.string.isRequired, isLoading: PropTypes.bool, showFilterSelection: PropTypes.bool, From 32cfade61ee19e7d5f1cdae4f280c90467764ac5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Ricks?= Date: Tue, 2 Oct 2018 10:47:46 +0200 Subject: [PATCH 06/25] Add a chartState to DataDisplay Allow to set and get state for charts in DataDisplay. Setting the state will also re-render the children which wouldn't be possible if a chart keeps the state internally in it's component. At a first step the showLegend state is put into the chart state. In future this chart state will be saved in the redux store too. --- .../dashboard/display/datadisplay.js | 40 ++++++++++++++++--- 1 file changed, 34 insertions(+), 6 deletions(-) diff --git a/gsa/src/web/components/dashboard/display/datadisplay.js b/gsa/src/web/components/dashboard/display/datadisplay.js index 33d2cb1b41..5cf35e9731 100644 --- a/gsa/src/web/components/dashboard/display/datadisplay.js +++ b/gsa/src/web/components/dashboard/display/datadisplay.js @@ -29,7 +29,7 @@ import equal from 'fast-deep-equal'; import _ from 'gmp/locale'; -import {isDefined} from 'gmp/utils/identity'; +import {isDefined, isFunction} from 'gmp/utils/identity'; import {excludeObjectProps} from 'gmp/utils/object'; import IconDivider from 'web/components/layout/icondivider'; @@ -127,12 +127,16 @@ class DataDisplay extends React.Component { data, originalData: this.props.data, title: this.props.title({data, id: this.props.id}), - showLegend: true, + chartState: { + showLegend: true, + ...this.props.initialChartState, + }, }; this.handleDownloadSvg = this.handleDownloadSvg.bind(this); this.handleDownloadCsv = this.handleDownloadCsv.bind(this); this.handleToggleLegend = this.handleToggleLegend.bind(this); + this.handleSetChartState = this.setChartState.bind(this); } static getDerivedStateFromProps(nextProps, prevState) { @@ -169,8 +173,8 @@ class DataDisplay extends React.Component { return nextProps.height !== this.props.height || nextProps.width !== this.props.width || nextState.data !== this.state.data || - nextState.showLegend !== this.state.showLegend || nextProps.showFilterString !== this.props.showFilterString || + nextState.chartState !== this.state.chartState || this.hasFilterChanged(nextProps); } @@ -214,6 +218,26 @@ class DataDisplay extends React.Component { } } + setChartState(state) { + if (isFunction(state)) { + this.setState(({chartState}) => ({ + chartState: { + ...chartState, + ...state(chartState), + }, + })); + } + else { + this.setState(({chartState}) => ({ + chartState: { + ...chartState, + ...state, + }, + })); + } + } + + handleDownloadSvg() { const {current: download} = this.downloadRef; @@ -249,14 +273,14 @@ class DataDisplay extends React.Component { } handleToggleLegend() { - this.setState(({showLegend}) => ({showLegend: !showLegend})); + this.setChartState(({showLegend}) => ({showLegend: !showLegend})); } render() { const { + chartState, data: transformedData, title, - showLegend, } = this.state; let { data: originalData, @@ -313,13 +337,16 @@ class DataDisplay extends React.Component { width, height, svgRef: this.svgRef, - showLegend, + state: chartState, + setState: this.handleSetChartState, })} } {icons && icons({ + state: chartState, + setState: this.handleSetChartState, showFilterSelection, showCsvDownload, showSvgDownload: hasSvg, @@ -357,6 +384,7 @@ DataDisplay.propTypes = { height: PropTypes.number.isRequired, icons: PropTypes.func, id: PropTypes.string.isRequired, + initialChartState: PropTypes.object, isLoading: PropTypes.bool, showFilterSelection: PropTypes.bool, showFilterString: PropTypes.bool, From b16d76391bee1275ae5870180a4400879663e4ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Ricks?= Date: Tue, 2 Oct 2018 11:04:43 +0200 Subject: [PATCH 07/25] Move MENU_PLACEHOLDER_WIDTH to a new js module Chart modules should not depend on dashboard components. Charts components are only for displaying some data and dashboards for orchestrating different displays which might be charts. --- gsa/CMakeLists.txt | 1 + gsa/src/web/components/chart/bar.js | 6 ++--- gsa/src/web/components/chart/donut.js | 5 +--- gsa/src/web/components/chart/line.js | 6 ++--- .../web/components/chart/utils/constants.js | 25 +++++++++++++++++++ .../dashboard/display/datadisplay.js | 2 -- .../components/dashboard/display/datatable.js | 4 +-- 7 files changed, 32 insertions(+), 17 deletions(-) create mode 100644 gsa/src/web/components/chart/utils/constants.js diff --git a/gsa/CMakeLists.txt b/gsa/CMakeLists.txt index d9f23ddffd..fc4a1f0c11 100644 --- a/gsa/CMakeLists.txt +++ b/gsa/CMakeLists.txt @@ -207,6 +207,7 @@ set (GSA_JS_SRC_FILES ${GSA_SRC_DIR}/src/web/components/chart/tooltip.js ${GSA_SRC_DIR}/src/web/components/chart/topology.js ${GSA_SRC_DIR}/src/web/components/chart/utils/arc.js + ${GSA_SRC_DIR}/src/web/components/chart/utils/constants.js ${GSA_SRC_DIR}/src/web/components/chart/utils/path.js ${GSA_SRC_DIR}/src/web/components/chart/wordcloud.js ${GSA_SRC_DIR}/src/web/components/comment/comment.js diff --git a/gsa/src/web/components/chart/bar.js b/gsa/src/web/components/chart/bar.js index 355c3f1adf..a61fe69b98 100644 --- a/gsa/src/web/components/chart/bar.js +++ b/gsa/src/web/components/chart/bar.js @@ -29,14 +29,12 @@ import {scaleBand, scaleLinear} from 'd3-scale'; import {shorten} from 'gmp/utils/string'; import {isDefined} from 'gmp/utils/identity'; -import { - MENU_PLACEHOLDER_WIDTH, -} from 'web/components/dashboard/display/datadisplay'; - import Layout from 'web/components/layout/layout'; import PropTypes from 'web/utils/proptypes'; +import {MENU_PLACEHOLDER_WIDTH} from './utils/constants'; + import Axis from './axis'; import Group from './group'; import Legend from './legend'; diff --git a/gsa/src/web/components/chart/donut.js b/gsa/src/web/components/chart/donut.js index 1046299546..f096116d39 100644 --- a/gsa/src/web/components/chart/donut.js +++ b/gsa/src/web/components/chart/donut.js @@ -36,10 +36,7 @@ import {setRef} from 'web/utils/render'; import Theme from 'web/utils/theme'; import arc from './utils/arc'; - -import { - MENU_PLACEHOLDER_WIDTH, -} from 'web/components/dashboard/display/datadisplay'; +import {MENU_PLACEHOLDER_WIDTH} from './utils/constants'; import Layout from 'web/components/layout/layout'; diff --git a/gsa/src/web/components/chart/line.js b/gsa/src/web/components/chart/line.js index cd7ebd7d1c..e0af035b7c 100644 --- a/gsa/src/web/components/chart/line.js +++ b/gsa/src/web/components/chart/line.js @@ -38,16 +38,14 @@ import {isDefined} from 'gmp/utils/identity'; import date from 'gmp/models/date'; -import { - MENU_PLACEHOLDER_WIDTH, -} from 'web/components/dashboard/display/datadisplay'; - import Layout from 'web/components/layout/layout'; import PropTypes from 'web/utils/proptypes'; import Theme from 'web/utils/theme'; import {setRef} from 'web/utils/render'; +import {MENU_PLACEHOLDER_WIDTH} from './utils/constants'; + import Legend, {Item, Label, Line as LegendLine} from './legend'; import Axis from './axis'; import Svg from './svg'; diff --git a/gsa/src/web/components/chart/utils/constants.js b/gsa/src/web/components/chart/utils/constants.js new file mode 100644 index 0000000000..4dece419a9 --- /dev/null +++ b/gsa/src/web/components/chart/utils/constants.js @@ -0,0 +1,25 @@ +/* Greenbone Security Assistant + * + * Authors: + * Björn Ricks + * + * Copyright: + * Copyright (C) 2018 Greenbone Networks GmbH + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + */ +export const MENU_PLACEHOLDER_WIDTH = 26; + +// vim: set ts=2 sw=2 tw=80: diff --git a/gsa/src/web/components/dashboard/display/datadisplay.js b/gsa/src/web/components/dashboard/display/datadisplay.js index 5cf35e9731..3e78fd27f7 100644 --- a/gsa/src/web/components/dashboard/display/datadisplay.js +++ b/gsa/src/web/components/dashboard/display/datadisplay.js @@ -45,8 +45,6 @@ import Display, { } from './display'; import DataDisplayIcons from './datadisplayicons'; -export const MENU_PLACEHOLDER_WIDTH = 26; - const ownProps = [ 'title', 'dataTransform', diff --git a/gsa/src/web/components/dashboard/display/datatable.js b/gsa/src/web/components/dashboard/display/datatable.js index 8360770661..b69bed999c 100644 --- a/gsa/src/web/components/dashboard/display/datatable.js +++ b/gsa/src/web/components/dashboard/display/datatable.js @@ -25,9 +25,7 @@ import React from 'react'; import styled from 'styled-components'; -import { - MENU_PLACEHOLDER_WIDTH, -} from 'web/components/dashboard/display/datadisplay'; +import {MENU_PLACEHOLDER_WIDTH} from 'web/components/chart/utils/constants'; import Table from 'web/components/table/stripedtable'; import TableHeader from 'web/components/table/header'; From 377f808ccc428eb4ecf97cfac72234e76bc6baae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Ricks?= Date: Tue, 2 Oct 2018 11:13:45 +0200 Subject: [PATCH 08/25] Add a default shouldUpdate implementation for charts Charts must be updates at least if data, width or height props have changed. --- gsa/CMakeLists.txt | 1 + .../chart/utils/__tests__/update.js | 52 +++++++++++++++++++ gsa/src/web/components/chart/utils/update.js | 39 ++++++++++++++ 3 files changed, 92 insertions(+) create mode 100644 gsa/src/web/components/chart/utils/__tests__/update.js create mode 100644 gsa/src/web/components/chart/utils/update.js diff --git a/gsa/CMakeLists.txt b/gsa/CMakeLists.txt index fc4a1f0c11..9f5cece5b5 100644 --- a/gsa/CMakeLists.txt +++ b/gsa/CMakeLists.txt @@ -209,6 +209,7 @@ set (GSA_JS_SRC_FILES ${GSA_SRC_DIR}/src/web/components/chart/utils/arc.js ${GSA_SRC_DIR}/src/web/components/chart/utils/constants.js ${GSA_SRC_DIR}/src/web/components/chart/utils/path.js + ${GSA_SRC_DIR}/src/web/components/chart/utils/update.js ${GSA_SRC_DIR}/src/web/components/chart/wordcloud.js ${GSA_SRC_DIR}/src/web/components/comment/comment.js ${GSA_SRC_DIR}/src/web/components/dashboard/controls.js diff --git a/gsa/src/web/components/chart/utils/__tests__/update.js b/gsa/src/web/components/chart/utils/__tests__/update.js new file mode 100644 index 0000000000..9f049af60d --- /dev/null +++ b/gsa/src/web/components/chart/utils/__tests__/update.js @@ -0,0 +1,52 @@ +/* Greenbone Security Assistant + * + * Authors: + * Björn Ricks + * + * Copyright: + * Copyright (C) 2018 Greenbone Networks GmbH + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + */ +import {shouldUpdate} from '../update'; + +describe('shouldUpdate tests', () => { + + test('should update if data identity has changed', () => { + expect(shouldUpdate({data: {}}, {data: {}})).toEqual(true); + }); + + test('should update if width has changed', () => { + expect(shouldUpdate({width: 100}, {width: 200})).toEqual(true); + }); + + test('should update if height has changed', () => { + expect(shouldUpdate({height: 100}, {height: 200})).toEqual(true); + }); + + test('should not update if data identity has not changed', () => { + const data = {foo: 1}; + expect(shouldUpdate({data}, {data})).toEqual(false); + }); + + test('should not update if width has not changed', () => { + expect(shouldUpdate({width: 100}, {width: 100})).toEqual(false); + }); + + test('should not update if height has not changed', () => { + expect(shouldUpdate({height: 100}, {height: 100})).toEqual(false); + }); + +}); diff --git a/gsa/src/web/components/chart/utils/update.js b/gsa/src/web/components/chart/utils/update.js new file mode 100644 index 0000000000..ddcff5f6c5 --- /dev/null +++ b/gsa/src/web/components/chart/utils/update.js @@ -0,0 +1,39 @@ +/* Greenbone Security Assistant + * + * Authors: + * Björn Ricks + * + * Copyright: + * Copyright (C) 2018 Greenbone Networks GmbH + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/** + * Default implementation for checking if a chart component must be updated + * + * A chart must always be re-rendered if data, width or height has changed. + * + * @param {Object} nextProps Next props to be set + * @param {Object} props Current set props + * + * @returns {Boolean} true if the chart component must be re-rendered + */ +export const shouldUpdate = (nextProps, props) => + nextProps.data !== props.data || + nextProps.width !== props.width || + nextProps.height !== props.height; + +// vim: set ts=2 sw=2 tw=80: From 49d243fa8d54925e8cd05339d34c8ac1f5b38f25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Ricks?= Date: Tue, 2 Oct 2018 11:18:56 +0200 Subject: [PATCH 09/25] Use new shouldUpdate for Line, Donut and Bar chart --- gsa/src/web/components/chart/bar.js | 5 ++--- gsa/src/web/components/chart/donut.js | 5 ++--- gsa/src/web/components/chart/line.js | 5 ++--- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/gsa/src/web/components/chart/bar.js b/gsa/src/web/components/chart/bar.js index a61fe69b98..2756420230 100644 --- a/gsa/src/web/components/chart/bar.js +++ b/gsa/src/web/components/chart/bar.js @@ -34,6 +34,7 @@ import Layout from 'web/components/layout/layout'; import PropTypes from 'web/utils/proptypes'; import {MENU_PLACEHOLDER_WIDTH} from './utils/constants'; +import {shouldUpdate} from './utils/update'; import Axis from './axis'; import Group from './group'; @@ -66,9 +67,7 @@ const tickFormat = val => { class BarChart extends React.Component { shouldComponentUpdate(nextProps) { - return this.props.width !== nextProps.width || - this.props.height !== nextProps.height || - this.props.data !== nextProps.data; + return shouldUpdate(nextProps, this.props); } render() { diff --git a/gsa/src/web/components/chart/donut.js b/gsa/src/web/components/chart/donut.js index f096116d39..a19ff25a12 100644 --- a/gsa/src/web/components/chart/donut.js +++ b/gsa/src/web/components/chart/donut.js @@ -37,6 +37,7 @@ import Theme from 'web/utils/theme'; import arc from './utils/arc'; import {MENU_PLACEHOLDER_WIDTH} from './utils/constants'; +import {shouldUpdate} from './utils/update'; import Layout from 'web/components/layout/layout'; @@ -149,9 +150,7 @@ class DonutChart extends React.Component { } shouldComponentUpdate(nextProps, nextState) { - return nextProps.data !== this.props.data || - nextProps.width !== this.props.width || - nextProps.height !== this.props.height || + return shouldUpdate(nextProps, this.props) || nextState.width !== this.state.width || nextProps.show3d !== this.props.show3d; } diff --git a/gsa/src/web/components/chart/line.js b/gsa/src/web/components/chart/line.js index e0af035b7c..011509afb0 100644 --- a/gsa/src/web/components/chart/line.js +++ b/gsa/src/web/components/chart/line.js @@ -45,6 +45,7 @@ import Theme from 'web/utils/theme'; import {setRef} from 'web/utils/render'; import {MENU_PLACEHOLDER_WIDTH} from './utils/constants'; +import {shouldUpdate} from './utils/update'; import Legend, {Item, Label, Line as LegendLine} from './legend'; import Axis from './axis'; @@ -206,9 +207,7 @@ class LineChart extends React.Component { } shouldComponentUpdate(nextProps, nextState) { - return nextProps.data !== this.props.data || - nextProps.width !== this.props.width || - nextProps.height !== this.props.height || + return shouldUpdate(nextProps, this.props) || nextState.width !== this.state.width || nextState.rangeX !== this.state.rangeX || nextState.infoX !== this.state.infoX || From 1c72750a310b9d0c448dcddc02dd423b09bb431c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Ricks?= Date: Tue, 2 Oct 2018 11:19:48 +0200 Subject: [PATCH 10/25] Fix indentation --- gsa/src/web/components/chart/donut.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gsa/src/web/components/chart/donut.js b/gsa/src/web/components/chart/donut.js index a19ff25a12..002e2a1b32 100644 --- a/gsa/src/web/components/chart/donut.js +++ b/gsa/src/web/components/chart/donut.js @@ -161,7 +161,7 @@ class DonutChart extends React.Component { if (width !== this.state.width) { this.setState({width}); } - this.separateLabels(); + this.separateLabels(); } componentDidUpdate() { From b483e9ecca691540de936c220bd12a7ea88c1452 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Ricks?= Date: Tue, 2 Oct 2018 11:28:00 +0200 Subject: [PATCH 11/25] Use showLegend prop to toggle displaying chart Legends Rename displayLegend of Bar chart to showLegend and add showLegend to Donut chart. --- gsa/src/web/components/chart/bar.js | 6 +++--- gsa/src/web/components/chart/donut.js | 5 ++++- .../web/components/dashboard/display/cvss/cvssdisplay.js | 2 +- gsa/src/web/pages/hosts/dashboard/vulnscoredisplay.js | 2 +- .../pages/operatingsystems/dashboard/vulnscoredisplay.js | 2 +- gsa/src/web/pages/tasks/dashboard/mosthighresults.js | 2 +- gsa/src/web/pages/vulns/dashboard/hostsdisplay.js | 2 +- 7 files changed, 12 insertions(+), 9 deletions(-) diff --git a/gsa/src/web/components/chart/bar.js b/gsa/src/web/components/chart/bar.js index 2756420230..6342ec05d0 100644 --- a/gsa/src/web/components/chart/bar.js +++ b/gsa/src/web/components/chart/bar.js @@ -73,7 +73,7 @@ class BarChart extends React.Component { render() { const { data = [], - displayLegend = true, + showLegend = true, height, xLabel = '', yLabel = '', @@ -192,7 +192,7 @@ class BarChart extends React.Component { ))} - {displayLegend && data.length > 0 && + {showLegend && data.length > 0 && this.legend = ref} data={data} @@ -223,9 +223,9 @@ BarChart.propTypes = { color: PropTypes.toString.isRequired, toolTip: PropTypes.elementOrString, })).isRequired, - displayLegend: PropTypes.bool, height: PropTypes.number.isRequired, horizontal: PropTypes.bool, + showLegend: PropTypes.bool, svgRef: PropTypes.ref, width: PropTypes.number.isRequired, xLabel: PropTypes.toString, diff --git a/gsa/src/web/components/chart/donut.js b/gsa/src/web/components/chart/donut.js index 002e2a1b32..8ef6e0cac9 100644 --- a/gsa/src/web/components/chart/donut.js +++ b/gsa/src/web/components/chart/donut.js @@ -152,6 +152,7 @@ class DonutChart extends React.Component { shouldComponentUpdate(nextProps, nextState) { return shouldUpdate(nextProps, this.props) || nextState.width !== this.state.width || + nextProps.showLegend !== this.props.showLegend || nextProps.show3d !== this.props.show3d; } @@ -237,6 +238,7 @@ class DonutChart extends React.Component { height, svgRef, show3d = true, + showLegend = true, onDataClick, onLegendItemClick, } = this.props; @@ -335,7 +337,7 @@ class DonutChart extends React.Component { /> } - {data.length > 0 && + {data.length > 0 && showLegend && ( Date: Tue, 2 Oct 2018 11:36:55 +0200 Subject: [PATCH 12/25] Fix calculating the Bar chart width with Legend displayed If the legend is displayed the Bar chart must be rendered again after the ref is set. Also update chart to use new React.createRef API. --- gsa/src/web/components/chart/bar.js | 63 ++++++++++++++++++++++------- 1 file changed, 49 insertions(+), 14 deletions(-) diff --git a/gsa/src/web/components/chart/bar.js b/gsa/src/web/components/chart/bar.js index 6342ec05d0..3d83b808b8 100644 --- a/gsa/src/web/components/chart/bar.js +++ b/gsa/src/web/components/chart/bar.js @@ -66,8 +66,52 @@ const tickFormat = val => { class BarChart extends React.Component { - shouldComponentUpdate(nextProps) { - return shouldUpdate(nextProps, this.props); + constructor(...args) { + super(...args); + + this.legendRef = React.createRef(); + + this.state = { + width: this.getWidth(), + }; + } + + shouldComponentUpdate(nextProps, nextState) { + return shouldUpdate(nextProps, this.props) || + nextState.width !== this.state.width; + } + + componentDidMount() { + this.update(); + } + + componentDidUpdate() { + this.update(); + } + + update() { + const width = this.getWidth(); + if (width !== this.state.width) { + this.setState({width}); + } + } + + getWidth() { + let {width} = this.props; + const {current: legend} = this.legendRef; + + width = width - MENU_PLACEHOLDER_WIDTH; + + if (legend !== null) { + const {width: legendWidth} = legend.getBoundingClientRect(); + width = width - legendWidth - LEGEND_MARGIN; + } + + if (width < MIN_WIDTH) { + width = MIN_WIDTH; + } + + return width; } render() { @@ -82,16 +126,7 @@ class BarChart extends React.Component { onDataClick, onLegendItemClick, } = this.props; - let {width} = this.props; - - if (this.legend) { - const {width: legendWidth} = this.legend.getBoundingClientRect(); - width = width - legendWidth - LEGEND_MARGIN; - } - - if (width < MIN_WIDTH) { - width = MIN_WIDTH; - } + const {width} = this.state; const xValues = data.map(d => d.x); const yValues = data.map(d => d.y); @@ -105,7 +140,7 @@ class BarChart extends React.Component { const marginLeft = horizontal ? margin.left + Math.min(MAX_LABEL_LENGTH, maxLabelLength) * 4 : margin.left; - const maxWidth = width - marginLeft - margin.right - MENU_PLACEHOLDER_WIDTH; + const maxWidth = width - marginLeft - margin.right; let maxHeight = height - margin.top - margin.bottom; if (isDefined(xLabel)) { @@ -194,7 +229,7 @@ class BarChart extends React.Component { {showLegend && data.length > 0 && this.legend = ref} + innerRef={this.legendRef} data={data} onItemClick={onLegendItemClick} /> From 36ed9251dfefed5d5a4703b3dc1291315c972afe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Ricks?= Date: Tue, 2 Oct 2018 12:16:18 +0200 Subject: [PATCH 13/25] Deactivate toggle legend buttons for charts without legends --- gsa/src/web/components/dashboard/display/cvss/cvssdisplay.js | 1 + gsa/src/web/components/dashboard/display/datatabledisplay.js | 1 + gsa/src/web/pages/hosts/dashboard/topologydisplay.js | 1 + gsa/src/web/pages/hosts/dashboard/vulnscoredisplay.js | 1 + gsa/src/web/pages/notes/dashboard/wordclouddisplay.js | 4 ++-- gsa/src/web/pages/nvts/dashboard/familydisplay.js | 3 ++- .../web/pages/operatingsystems/dashboard/vulnscoredisplay.js | 1 + gsa/src/web/pages/overrides/dashboard/wordclouddisplay.js | 1 + .../pages/results/dashboard/descriptionwordclouddisplay.js | 5 ++--- gsa/src/web/pages/results/dashboard/wordclouddisplay.js | 5 ++--- gsa/src/web/pages/tasks/dashboard/highresults.js | 1 + gsa/src/web/pages/tasks/dashboard/mosthighresults.js | 1 + gsa/src/web/pages/tasks/dashboard/schedulesdisplay.js | 1 + gsa/src/web/pages/vulns/dashboard/hostsdisplay.js | 5 +++-- 14 files changed, 20 insertions(+), 11 deletions(-) diff --git a/gsa/src/web/components/dashboard/display/cvss/cvssdisplay.js b/gsa/src/web/components/dashboard/display/cvss/cvssdisplay.js index 7dde09bdf7..f6e00dfa54 100644 --- a/gsa/src/web/components/dashboard/display/cvss/cvssdisplay.js +++ b/gsa/src/web/components/dashboard/display/cvss/cvssdisplay.js @@ -111,6 +111,7 @@ class CvssDisplay extends React.Component { {...props} dataTransform={transformCvssData} title={title} + showToggleLegend={false} > {({width, height, data, svgRef}) => ( {({data}) => ( isDefined(children) ? diff --git a/gsa/src/web/pages/hosts/dashboard/topologydisplay.js b/gsa/src/web/pages/hosts/dashboard/topologydisplay.js index 9937ee3ee6..af64997d9b 100644 --- a/gsa/src/web/pages/hosts/dashboard/topologydisplay.js +++ b/gsa/src/web/pages/hosts/dashboard/topologydisplay.js @@ -157,6 +157,7 @@ export class HostsTopologyDisplay extends React.Component { filter={filter} dataTransform={transformTopologyData} title={() => _('Hosts Topology')} + showToggleLegend={false} > {({width, height, data: tdata, svgRef}) => ( _('Most Vulnerable Hosts')} + showToggleLegend={false} > {({width, height, data: tdata, svgRef}) => ( - _('Notes Text Word Cloud')} + title={() => _('Notes Text Word Cloud')} + showToggleLegend={false} > {({width, height, data: tdata, svgRef}) => ( - _('NVTS by Family (Total: {{count}})', {count: tdata.total})} + _('NVTS by Family (Total: {{count}})', {count: tdata.total})} + showToggleLegend={false} > {({width, height, data: tdata, svgRef}) => ( _('Most Vulnerable Operating Systems')} + showToggleLegend={false} > {({width, height, data: tdata, svgRef}) => ( _('Overrides Text Word Cloud')} + showToggleLegend={false} > {({width, height, data: tdata, svgRef}) => ( - _('Results Description Word Cloud')} + title={() => _('Results Description Word Cloud')} + showToggleLegend={false} > {({width, height, data: tdata, svgRef}) => ( - _('Results Vulnerability Word Cloud')} + title={() => _('Results Vulnerability Word Cloud')} + showToggleLegend={false} > {({width, height, data: tdata, svgRef}) => ( _('Tasks by High Results per Host')} + showToggleLegend={false} > {({width, height, data: tdata, svgRef}) => ( [row.x, row.y]} dataTransform={transformHighResultsData} title={() => _('Tasks with most High Results per Host')} + showToggleLegend={false} > {({width, height, data: tdata, svgRef}) => ( - _('Vulnerabilities by Hosts (Total: {{count}})', - {count: tdata.total})} + _('Vulnerabilities by Hosts (Total: {{count}})', + {count: tdata.total})} + showToggleLegend={false} > {({width, height, data: tdata, svgRef}) => ( Date: Tue, 2 Oct 2018 14:08:10 +0200 Subject: [PATCH 14/25] Move LineChart proptypes to the bottom We have mostly all proptypes at the bottom of the js module. Therefore it's demanding to search for the LineChart proptypes. --- gsa/src/web/components/chart/line.js | 47 ++++++++++++++-------------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/gsa/src/web/components/chart/line.js b/gsa/src/web/components/chart/line.js index 011509afb0..885c60af30 100644 --- a/gsa/src/web/components/chart/line.js +++ b/gsa/src/web/components/chart/line.js @@ -155,29 +155,6 @@ CrossY2.propTypes = crossPropTypes; class LineChart extends React.Component { - static propTypes = { - data: PropTypes.arrayOf(PropTypes.shape({ - x: PropTypes.oneOfType([ - PropTypes.number, - PropTypes.date, - ]).isRequired, - y: PropTypes.number.isRequired, - y2: PropTypes.number.isRequired, - })), - displayLegend: PropTypes.bool, - height: PropTypes.number.isRequired, - numTicks: PropTypes.number, - svgRef: PropTypes.ref, - timeline: PropTypes.bool, - width: PropTypes.number.isRequired, - xAxisLabel: PropTypes.toString, - y2AxisLabel: PropTypes.toString, - y2Line: lineDataPropType, - yAxisLabel: PropTypes.toString, - yLine: lineDataPropType, - onRangeSelected: PropTypes.func, - }; - constructor(...args) { super(...args); @@ -685,6 +662,30 @@ class LineChart extends React.Component { } } +LineChart.propTypes = { + data: PropTypes.arrayOf(PropTypes.shape({ + x: PropTypes.oneOfType([ + PropTypes.number, + PropTypes.date, + ]).isRequired, + y: PropTypes.number.isRequired, + y2: PropTypes.number.isRequired, + })), + displayLegend: PropTypes.bool, + height: PropTypes.number.isRequired, + numTicks: PropTypes.number, + svgRef: PropTypes.ref, + timeline: PropTypes.bool, + width: PropTypes.number.isRequired, + xAxisLabel: PropTypes.toString, + y2AxisLabel: PropTypes.toString, + y2Line: lineDataPropType, + yAxisLabel: PropTypes.toString, + yLine: lineDataPropType, + onRangeSelected: PropTypes.func, +}; + + export default LineChart; // vim: set ts=2 sw=2 tw=80: From bc3271ab85397b857bbbc30d31aa6cea92ce8170 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Ricks?= Date: Tue, 2 Oct 2018 14:09:49 +0200 Subject: [PATCH 15/25] Rename displayLegend into showLegend Use showLegend prop instead of displayLegend at LineChart. --- gsa/src/web/components/chart/line.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gsa/src/web/components/chart/line.js b/gsa/src/web/components/chart/line.js index 885c60af30..f2f1f57978 100644 --- a/gsa/src/web/components/chart/line.js +++ b/gsa/src/web/components/chart/line.js @@ -524,7 +524,7 @@ class LineChart extends React.Component { } = this.state; const { data = [], - displayLegend = true, + showLegend = true, svgRef, xAxisLabel, yAxisLabel, @@ -638,7 +638,7 @@ class LineChart extends React.Component { {this.renderRange()} - {hasLines && displayLegend && + {hasLines && showLegend && Date: Tue, 2 Oct 2018 14:10:56 +0200 Subject: [PATCH 16/25] Don't crash if svg ref isn't set in LineChart --- gsa/src/web/components/chart/line.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gsa/src/web/components/chart/line.js b/gsa/src/web/components/chart/line.js index f2f1f57978..564c99eec7 100644 --- a/gsa/src/web/components/chart/line.js +++ b/gsa/src/web/components/chart/line.js @@ -175,7 +175,6 @@ class LineChart extends React.Component { } componentDidUpdate() { - this.setState(this.update()); } @@ -202,6 +201,10 @@ class LineChart extends React.Component { } handleMouseMove(event) { + if (!this.svg) { + return; + } + const box = this.svg.getBoundingClientRect(); const mouseX = event.clientX - box.left - margin.left - 1; From bf2d14a117759898483e33704944bea61f765d0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Ricks?= Date: Tue, 2 Oct 2018 14:11:28 +0200 Subject: [PATCH 17/25] Use shouldUpdate func at ScheduleChart --- gsa/src/web/components/chart/schedule.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gsa/src/web/components/chart/schedule.js b/gsa/src/web/components/chart/schedule.js index 06ae961ced..2e8066e8f1 100644 --- a/gsa/src/web/components/chart/schedule.js +++ b/gsa/src/web/components/chart/schedule.js @@ -40,6 +40,8 @@ import Theme from '../../utils/theme'; import Layout from '../layout/layout'; import path from './utils/path'; +import {shouldUpdate} from './utils/update'; + import Axis from './axis'; import Svg from './svg'; import ToolTip from './tooltip'; @@ -191,9 +193,7 @@ Triangle.propTypes = { class ScheduleChart extends React.Component { shouldComponentUpdate(nextProps) { - return nextProps.data !== this.props.data || - nextProps.width !== this.props.width || - nextProps.height !== this.props.height; + return shouldUpdate(nextProps, this.props); } render() { From 1dc6076f35e6061c7325b0882481334121163035 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Ricks?= Date: Tue, 2 Oct 2018 14:12:21 +0200 Subject: [PATCH 18/25] Avoid crashing DataDisplay on svg download Never crash if svg or download refs aren't set. This should not ever happen but it is saver to check for this case. --- gsa/src/web/components/dashboard/display/datadisplay.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/gsa/src/web/components/dashboard/display/datadisplay.js b/gsa/src/web/components/dashboard/display/datadisplay.js index 3e78fd27f7..1c6fd97166 100644 --- a/gsa/src/web/components/dashboard/display/datadisplay.js +++ b/gsa/src/web/components/dashboard/display/datadisplay.js @@ -235,9 +235,14 @@ class DataDisplay extends React.Component { } } - handleDownloadSvg() { const {current: download} = this.downloadRef; + const {current: svg} = this.svgRef; + + if (!svg || !download) { + // don't crash if refs haven't been set in some way + return; + } this.cleanupDownloadSvg(); From 041ead1c324900eae4ee9577bfe10aa787c6172d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Ricks?= Date: Tue, 2 Oct 2018 14:13:55 +0200 Subject: [PATCH 19/25] Fix displaying the svg download icon When the svg ref is set in a child of DataDisplay the component will not be re-rendered necessarily. Therefore the svg ref may be set but the icon is still not displayed. Therefore add an external prop to deactivate the svg download icon on demand. --- gsa/src/web/components/dashboard/display/datadisplay.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gsa/src/web/components/dashboard/display/datadisplay.js b/gsa/src/web/components/dashboard/display/datadisplay.js index 1c6fd97166..49197ddaef 100644 --- a/gsa/src/web/components/dashboard/display/datadisplay.js +++ b/gsa/src/web/components/dashboard/display/datadisplay.js @@ -300,6 +300,7 @@ class DataDisplay extends React.Component { dataRow, filter, icons = renderIcons, + showSvgDownload, showToggleLegend, onSelectFilterClick, onRemoveClick, @@ -320,8 +321,6 @@ class DataDisplay extends React.Component { } const showContent = height > 0 && width > 0; // > 0 also checks for null, undefined and null - const {current: svg} = this.svgRef; - const hasSvg = !!svg; return ( Date: Tue, 2 Oct 2018 14:17:03 +0200 Subject: [PATCH 20/25] Disable svg downloads for data table displays When displaying a table it shouldn't be possible to download a svg. --- gsa/src/web/components/dashboard/display/datatabledisplay.js | 1 + 1 file changed, 1 insertion(+) diff --git a/gsa/src/web/components/dashboard/display/datatabledisplay.js b/gsa/src/web/components/dashboard/display/datatabledisplay.js index 0b2858ccda..5970755111 100644 --- a/gsa/src/web/components/dashboard/display/datatabledisplay.js +++ b/gsa/src/web/components/dashboard/display/datatabledisplay.js @@ -40,6 +40,7 @@ const DataTableDisplay = ({ {...props} dataRow={dataRow} dataTitles={dataTitles} + showSvgDownload={false} showToggleLegend={false} > {({data}) => ( From 274deff5b83603a8d58cc0dfc96b0dd7aaa76e84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Ricks?= Date: Tue, 2 Oct 2018 15:09:01 +0200 Subject: [PATCH 21/25] Allow to toggle legends of different charts --- .../components/dashboard/display/created/createddisplay.js | 3 ++- .../dashboard/display/severity/severityclassdisplay.js | 3 ++- gsa/src/web/pages/hosts/dashboard/modifieddisplay.js | 3 ++- gsa/src/web/pages/hosts/dashboard/modifiedhighdisplay.js | 3 ++- gsa/src/web/pages/notes/dashboard/activedaysdisplay.js | 3 ++- gsa/src/web/pages/nvts/dashboard/qoddisplay.js | 3 ++- gsa/src/web/pages/nvts/dashboard/qodtypedisplay.js | 3 ++- gsa/src/web/pages/overrides/dashboard/activedaysdisplay.js | 3 ++- gsa/src/web/pages/reports/dashboard/highresultsdisplay.js | 6 +++--- gsa/src/web/pages/tasks/dashboard/statusdisplay.js | 3 ++- 10 files changed, 21 insertions(+), 12 deletions(-) diff --git a/gsa/src/web/components/dashboard/display/created/createddisplay.js b/gsa/src/web/components/dashboard/display/created/createddisplay.js index 7c20b61fc8..775fd7fbbf 100644 --- a/gsa/src/web/components/dashboard/display/created/createddisplay.js +++ b/gsa/src/web/components/dashboard/display/created/createddisplay.js @@ -99,7 +99,7 @@ class CreatedDisplay extends React.Component { dataTransform={transformCreated} filter={filter} > - {({width, height, data: tdata, svgRef}) => ( + {({width, height, data: tdata, svgRef, state}) => ( diff --git a/gsa/src/web/components/dashboard/display/severity/severityclassdisplay.js b/gsa/src/web/components/dashboard/display/severity/severityclassdisplay.js index 4f3a48a313..88336f3631 100644 --- a/gsa/src/web/components/dashboard/display/severity/severityclassdisplay.js +++ b/gsa/src/web/components/dashboard/display/severity/severityclassdisplay.js @@ -103,12 +103,13 @@ class SeverityClassDisplay extends React.Component { {...props} dataTransform={transformSeverityData} > - {({width, height, data, svgRef}) => ( + {({width, height, data, svgRef, state}) => ( - {({width, height, data: tdata, svgRef}) => ( + {({width, height, data: tdata, svgRef, state}) => ( )} diff --git a/gsa/src/web/pages/hosts/dashboard/modifiedhighdisplay.js b/gsa/src/web/pages/hosts/dashboard/modifiedhighdisplay.js index f07eaea533..88bc776c75 100644 --- a/gsa/src/web/pages/hosts/dashboard/modifiedhighdisplay.js +++ b/gsa/src/web/pages/hosts/dashboard/modifiedhighdisplay.js @@ -133,7 +133,7 @@ export class HostsModifiedHighDisplay extends React.Component { {count: tdata.total}) } > - {({width, height, data: tdata, svgRef}) => ( + {({width, height, data: tdata, svgRef, state}) => ( )} diff --git a/gsa/src/web/pages/notes/dashboard/activedaysdisplay.js b/gsa/src/web/pages/notes/dashboard/activedaysdisplay.js index e03efab9ee..f248bd07d8 100644 --- a/gsa/src/web/pages/notes/dashboard/activedaysdisplay.js +++ b/gsa/src/web/pages/notes/dashboard/activedaysdisplay.js @@ -171,12 +171,13 @@ export class NotesActiveDaysDisplay extends React.Component { title={({data: tdata}) => _('Notes by Active Days (Total: ' + '{{count}})', {count: tdata.total})} > - {({width, height, data: tdata, svgRef}) => ( + {({width, height, data: tdata, svgRef, state}) => ( diff --git a/gsa/src/web/pages/nvts/dashboard/qoddisplay.js b/gsa/src/web/pages/nvts/dashboard/qoddisplay.js index 4352a8c635..955f487b3a 100644 --- a/gsa/src/web/pages/nvts/dashboard/qoddisplay.js +++ b/gsa/src/web/pages/nvts/dashboard/qoddisplay.js @@ -118,12 +118,13 @@ export class NvtsQodDisplay extends React.Component { title={({data: tdata}) => _('NVTs by QoD (Total: {{count}})', {count: tdata.total})} > - {({width, height, data: tdata, svgRef}) => ( + {({width, height, data: tdata, svgRef, state}) => ( diff --git a/gsa/src/web/pages/nvts/dashboard/qodtypedisplay.js b/gsa/src/web/pages/nvts/dashboard/qodtypedisplay.js index 8831742d24..7b459db9ad 100644 --- a/gsa/src/web/pages/nvts/dashboard/qodtypedisplay.js +++ b/gsa/src/web/pages/nvts/dashboard/qodtypedisplay.js @@ -116,12 +116,13 @@ export class NvtsQodTypeDisplay extends React.Component { title={({data: tdata}) => _('NVTs by QoD-Type (Total: {{count}})', {count: tdata.total})} > - {({width, height, data: tdata, svgRef}) => ( + {({width, height, data: tdata, svgRef, state}) => ( diff --git a/gsa/src/web/pages/overrides/dashboard/activedaysdisplay.js b/gsa/src/web/pages/overrides/dashboard/activedaysdisplay.js index eebd36aa96..91d80c558d 100644 --- a/gsa/src/web/pages/overrides/dashboard/activedaysdisplay.js +++ b/gsa/src/web/pages/overrides/dashboard/activedaysdisplay.js @@ -169,12 +169,13 @@ export class OverridesActiveDaysDisplay extends React.Component { title={({data: tdata}) => _('Overrides by Active Days (Total: ' + '{{count}})', {count: tdata.total})} > - {({width, height, data: tdata, svgRef}) => ( + {({width, height, data: tdata, svgRef, state}) => ( diff --git a/gsa/src/web/pages/reports/dashboard/highresultsdisplay.js b/gsa/src/web/pages/reports/dashboard/highresultsdisplay.js index 04a6ea1e7b..11ae9a9911 100644 --- a/gsa/src/web/pages/reports/dashboard/highresultsdisplay.js +++ b/gsa/src/web/pages/reports/dashboard/highresultsdisplay.js @@ -118,10 +118,9 @@ export class ReportsHighResultsDisplay extends React.Component { {...loaderProps} dataTransform={transformHighResults} filter={filter} - title={({data: tdata}) => - _('Reports with High Results')} + title={() => _('Reports with High Results')} > - {({width, height, data: tdata, svgRef}) => ( + {({width, height, data: tdata, svgRef, state}) => ( )} diff --git a/gsa/src/web/pages/tasks/dashboard/statusdisplay.js b/gsa/src/web/pages/tasks/dashboard/statusdisplay.js index 97e25abbbc..00f0a5cc74 100644 --- a/gsa/src/web/pages/tasks/dashboard/statusdisplay.js +++ b/gsa/src/web/pages/tasks/dashboard/statusdisplay.js @@ -151,12 +151,13 @@ export class TasksStatusDisplay extends React.Component { title={({data: tdata}) => _('Tasks by Status (Total: {{count}})', {count: tdata.total})} > - {({width, height, data: tdata, svgRef}) => ( + {({width, height, data: tdata, svgRef, state}) => ( Date: Tue, 2 Oct 2018 15:09:30 +0200 Subject: [PATCH 22/25] Fix LineChart update Only re-calculate state from width if the width has changed actually. Th LineChart did crash because the width has been re-calculated when hovering over the LineChart to display the tooltips. This lead to an infinite loop. Also fix calculation of the width. It uses the same pattern as the donut chart now. --- gsa/src/web/components/chart/line.js | 34 +++++++++++++++++----------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/gsa/src/web/components/chart/line.js b/gsa/src/web/components/chart/line.js index 564c99eec7..0cc777241b 100644 --- a/gsa/src/web/components/chart/line.js +++ b/gsa/src/web/components/chart/line.js @@ -170,16 +170,16 @@ class LineChart extends React.Component { this.state = { displayInfo: false, - ...this.update(), + ...this.stateFromWidth(this.getWidth()), }; } componentDidUpdate() { - this.setState(this.update()); + this.update(); } componentDidMount() { - this.setState(this.update()); + this.update(); } shouldComponentUpdate(nextProps, nextState) { @@ -282,29 +282,37 @@ class LineChart extends React.Component { } getWidth() { - const {width} = this.props; + let {width} = this.props; const {current: legend} = this.legendRef; - if (legend === null) { - return width; + width = width - MENU_PLACEHOLDER_WIDTH; + + if (legend !== null) { + const {width: legendWidth} = legend.getBoundingClientRect(); + width = width - legendWidth - LEGEND_MARGIN; + } + + if (width < MIN_WIDTH) { + width = MIN_WIDTH; } - const {width: legendWidth} = legend.getBoundingClientRect(); - return width - legendWidth - LEGEND_MARGIN - MENU_PLACEHOLDER_WIDTH; + return width; } update() { + const width = this.getWidth(); + if (width !== this.state.width) { + this.setState(this.stateFromWidth(width)); + } + } + + stateFromWidth(width) { const { data = [], height, timeline = false, } = this.props; - let width = this.getWidth(); - if (width < MIN_WIDTH) { - width = MIN_WIDTH; - } - const maxWidth = width - margin.left - margin.right; const maxHeight = height - margin.top - margin.bottom; From 741028da1c6d9c247904344b15ea3131f965126d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Ricks?= Date: Tue, 2 Oct 2018 15:11:39 +0200 Subject: [PATCH 23/25] Update shouldUpdate to consider showLegend prop A chart should be re-rendered if the showLegend prop has changed. --- gsa/src/web/components/chart/donut.js | 1 - .../web/components/chart/utils/__tests__/update.js | 12 ++++++++++++ gsa/src/web/components/chart/utils/update.js | 3 ++- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/gsa/src/web/components/chart/donut.js b/gsa/src/web/components/chart/donut.js index 8ef6e0cac9..615ffa8bbf 100644 --- a/gsa/src/web/components/chart/donut.js +++ b/gsa/src/web/components/chart/donut.js @@ -152,7 +152,6 @@ class DonutChart extends React.Component { shouldComponentUpdate(nextProps, nextState) { return shouldUpdate(nextProps, this.props) || nextState.width !== this.state.width || - nextProps.showLegend !== this.props.showLegend || nextProps.show3d !== this.props.show3d; } diff --git a/gsa/src/web/components/chart/utils/__tests__/update.js b/gsa/src/web/components/chart/utils/__tests__/update.js index 9f049af60d..0032ab7118 100644 --- a/gsa/src/web/components/chart/utils/__tests__/update.js +++ b/gsa/src/web/components/chart/utils/__tests__/update.js @@ -36,6 +36,10 @@ describe('shouldUpdate tests', () => { expect(shouldUpdate({height: 100}, {height: 200})).toEqual(true); }); + test('should update if showLegend has changed', () => { + expect(shouldUpdate({showLegend: false}, {showLegend: true})).toEqual(true); + }); + test('should not update if data identity has not changed', () => { const data = {foo: 1}; expect(shouldUpdate({data}, {data})).toEqual(false); @@ -49,4 +53,12 @@ describe('shouldUpdate tests', () => { expect(shouldUpdate({height: 100}, {height: 100})).toEqual(false); }); + test('should not update if showLegend has not changed', () => { + expect(shouldUpdate({showLegend: true}, {showLegend: true})).toEqual(false); + }); + + test('should not update if unkown prop has changed', () => { + expect(shouldUpdate({foo: false}, {foo: true})).toEqual(false); + }); + }); diff --git a/gsa/src/web/components/chart/utils/update.js b/gsa/src/web/components/chart/utils/update.js index ddcff5f6c5..c812bf060d 100644 --- a/gsa/src/web/components/chart/utils/update.js +++ b/gsa/src/web/components/chart/utils/update.js @@ -34,6 +34,7 @@ export const shouldUpdate = (nextProps, props) => nextProps.data !== props.data || nextProps.width !== props.width || - nextProps.height !== props.height; + nextProps.height !== props.height || + nextProps.showLegend !== props.showLegend; // vim: set ts=2 sw=2 tw=80: From 9ae37ac83ccec7ae749faa1c01df4d607878148d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Ricks?= Date: Tue, 2 Oct 2018 15:59:25 +0200 Subject: [PATCH 24/25] Allow to toggle 2d/3d donut view --- .../dashboard/display/datadisplayicons.js | 16 ++++++++++++ .../display/severity/severityclassdisplay.js | 6 +++++ .../notes/dashboard/activedaysdisplay.js | 6 +++++ .../web/pages/nvts/dashboard/qoddisplay.js | 6 +++++ .../pages/nvts/dashboard/qodtypedisplay.js | 6 +++++ .../pages/ovaldefs/dashboard/classdisplay.js | 25 +++++++++++++------ .../overrides/dashboard/activedaysdisplay.js | 6 +++++ .../pages/secinfo/dashboard/typedisplay.js | 10 +++++++- .../pages/tasks/dashboard/statusdisplay.js | 8 ++++++ 9 files changed, 80 insertions(+), 9 deletions(-) diff --git a/gsa/src/web/components/dashboard/display/datadisplayicons.js b/gsa/src/web/components/dashboard/display/datadisplayicons.js index b10c544450..b0707f571b 100644 --- a/gsa/src/web/components/dashboard/display/datadisplayicons.js +++ b/gsa/src/web/components/dashboard/display/datadisplayicons.js @@ -28,6 +28,22 @@ import Icon from 'web/components/icon/icon'; import PropTypes from 'web/utils/proptypes'; +export const renderDonutChartIcons = ({ + setState, // eslint-disable-line react/prop-types + ...iconsProps +}) => ( + + + setState(({show3d}) => ({show3d: !show3d}))} + /> + +); + const DataDisplayIcons = ({ showCsvDownload = true, showSvgDownload = true, diff --git a/gsa/src/web/components/dashboard/display/severity/severityclassdisplay.js b/gsa/src/web/components/dashboard/display/severity/severityclassdisplay.js index 88336f3631..96d949c21e 100644 --- a/gsa/src/web/components/dashboard/display/severity/severityclassdisplay.js +++ b/gsa/src/web/components/dashboard/display/severity/severityclassdisplay.js @@ -34,6 +34,7 @@ import PropTypes from 'web/utils/proptypes'; import DonutChart from 'web/components/chart/donut'; import DataDisplay from '../datadisplay'; +import {renderDonutChartIcons} from '../datadisplayicons'; import transformSeverityData from './severityclasstransform'; @@ -101,7 +102,11 @@ class SeverityClassDisplay extends React.Component { return ( {({width, height, data, svgRef, state}) => ( _('Notes by Active Days (Total: ' + '{{count}})', {count: tdata.total})} + initialChartState={{ + show3d: true, + }} + icons={renderDonutChartIcons} > {({width, height, data: tdata, svgRef, state}) => ( _('NVTs by QoD (Total: {{count}})', {count: tdata.total})} + initialChartState={{ + show3d: true, + }} + icons={renderDonutChartIcons} > {({width, height, data: tdata, svgRef, state}) => ( _('NVTs by QoD-Type (Total: {{count}})', {count: tdata.total})} + initialChartState={{ + show3d: true, + }} + icons={renderDonutChartIcons} > {({width, height, data: tdata, svgRef, state}) => ( { @@ -117,13 +120,19 @@ export class OvaldefClassDisplay extends React.Component { title={({data: tdata}) => _('OVAL Definitions by Class (Total: {{count}})', {count: tdata.total})} + initialChartState={{ + show3d: true, + }} + icons={renderDonutChartIcons} > - {({width, height, data: tdata, svgRef}) => ( + {({width, height, data: tdata, svgRef, state}) => ( diff --git a/gsa/src/web/pages/overrides/dashboard/activedaysdisplay.js b/gsa/src/web/pages/overrides/dashboard/activedaysdisplay.js index 91d80c558d..ca6f24d865 100644 --- a/gsa/src/web/pages/overrides/dashboard/activedaysdisplay.js +++ b/gsa/src/web/pages/overrides/dashboard/activedaysdisplay.js @@ -35,6 +35,7 @@ import PropTypes from 'web/utils/proptypes'; import DonutChart from 'web/components/chart/donut'; import DataDisplay from 'web/components/dashboard/display/datadisplay'; +import {renderDonutChartIcons} from 'web/components/dashboard/display/datadisplayicons'; // eslint-disable-line max-len import DataTableDisplay from 'web/components/dashboard/display/datatabledisplay'; // eslint-disable-line max-len import withFilterSelection from 'web/components/dashboard/display/withFilterSelection'; // eslint-disable-line max-len import createDisplay from 'web/components/dashboard/display/createDisplay'; @@ -168,6 +169,10 @@ export class OverridesActiveDaysDisplay extends React.Component { dataTransform={transformActiveDaysData} title={({data: tdata}) => _('Overrides by Active Days (Total: ' + '{{count}})', {count: tdata.total})} + initialChartState={{ + show3d: true, + }} + icons={renderDonutChartIcons} > {({width, height, data: tdata, svgRef, state}) => ( _('SecInfo Items by Type (Total: {{count}})', {count: tdata.total})} + initialChartState={{ + show3d: true, + }} + icons={renderDonutChartIcons} > - {({width, height, data: tdata, svgRef}) => ( + {({width, height, data: tdata, svgRef, state}) => ( diff --git a/gsa/src/web/pages/tasks/dashboard/statusdisplay.js b/gsa/src/web/pages/tasks/dashboard/statusdisplay.js index 00f0a5cc74..8f272cecbc 100644 --- a/gsa/src/web/pages/tasks/dashboard/statusdisplay.js +++ b/gsa/src/web/pages/tasks/dashboard/statusdisplay.js @@ -40,6 +40,9 @@ import PropTypes from 'web/utils/proptypes'; import DonutChart from 'web/components/chart/donut'; import DataDisplay from 'web/components/dashboard/display/datadisplay'; +import { + renderDonutChartIcons, +} from 'web/components/dashboard/display/datadisplayicons'; import DataTable from 'web/components/dashboard/display/datatable'; import DataTableDisplay from 'web/components/dashboard/display/datatabledisplay'; // eslint-disable-line max-len import createDisplay from 'web/components/dashboard/display/createDisplay'; @@ -146,10 +149,14 @@ export class TasksStatusDisplay extends React.Component { _('Tasks by Status (Total: {{count}})', {count: tdata.total})} + icons={renderDonutChartIcons} > {({width, height, data: tdata, svgRef, state}) => ( Date: Tue, 2 Oct 2018 16:23:34 +0200 Subject: [PATCH 25/25] Rename chart state to child state Use initialState instead of initialChartState because the internal state variable name isn't visible outside of DataDisplay component. For children it's only the state. --- .../dashboard/display/datadisplay.js | 32 +++++++++---------- .../display/severity/severityclassdisplay.js | 2 +- .../notes/dashboard/activedaysdisplay.js | 2 +- .../web/pages/nvts/dashboard/qoddisplay.js | 2 +- .../pages/nvts/dashboard/qodtypedisplay.js | 2 +- .../pages/ovaldefs/dashboard/classdisplay.js | 2 +- .../overrides/dashboard/activedaysdisplay.js | 2 +- .../pages/secinfo/dashboard/typedisplay.js | 2 +- .../pages/tasks/dashboard/statusdisplay.js | 2 +- 9 files changed, 24 insertions(+), 24 deletions(-) diff --git a/gsa/src/web/components/dashboard/display/datadisplay.js b/gsa/src/web/components/dashboard/display/datadisplay.js index 49197ddaef..b9a3b42648 100644 --- a/gsa/src/web/components/dashboard/display/datadisplay.js +++ b/gsa/src/web/components/dashboard/display/datadisplay.js @@ -125,16 +125,16 @@ class DataDisplay extends React.Component { data, originalData: this.props.data, title: this.props.title({data, id: this.props.id}), - chartState: { + childState: { showLegend: true, - ...this.props.initialChartState, + ...this.props.initialState, }, }; this.handleDownloadSvg = this.handleDownloadSvg.bind(this); this.handleDownloadCsv = this.handleDownloadCsv.bind(this); this.handleToggleLegend = this.handleToggleLegend.bind(this); - this.handleSetChartState = this.setChartState.bind(this); + this.handleSetChildState = this.setChildState.bind(this); } static getDerivedStateFromProps(nextProps, prevState) { @@ -216,19 +216,19 @@ class DataDisplay extends React.Component { } } - setChartState(state) { + setChildState(state) { if (isFunction(state)) { - this.setState(({chartState}) => ({ - chartState: { - ...chartState, - ...state(chartState), + this.setState(({childState}) => ({ + childState: { + ...childState, + ...state(childState), }, })); } else { - this.setState(({chartState}) => ({ - chartState: { - ...chartState, + this.setState(({childState}) => ({ + childState: { + ...childState, ...state, }, })); @@ -281,7 +281,7 @@ class DataDisplay extends React.Component { render() { const { - chartState, + childState, data: transformedData, title, } = this.state; @@ -339,7 +339,7 @@ class DataDisplay extends React.Component { width, height, svgRef: this.svgRef, - state: chartState, + state: childState, setState: this.handleSetChartState, })} @@ -347,8 +347,8 @@ class DataDisplay extends React.Component { {icons && icons({ - state: chartState, - setState: this.handleSetChartState, + state: childState, + setState: this.handleSetChildState, showFilterSelection, showCsvDownload, showSvgDownload, @@ -386,7 +386,7 @@ DataDisplay.propTypes = { height: PropTypes.number.isRequired, icons: PropTypes.func, id: PropTypes.string.isRequired, - initialChartState: PropTypes.object, + initialState: PropTypes.object, isLoading: PropTypes.bool, showFilterSelection: PropTypes.bool, showFilterString: PropTypes.bool, diff --git a/gsa/src/web/components/dashboard/display/severity/severityclassdisplay.js b/gsa/src/web/components/dashboard/display/severity/severityclassdisplay.js index 96d949c21e..bec0ea55c1 100644 --- a/gsa/src/web/components/dashboard/display/severity/severityclassdisplay.js +++ b/gsa/src/web/components/dashboard/display/severity/severityclassdisplay.js @@ -102,7 +102,7 @@ class SeverityClassDisplay extends React.Component { return ( _('Notes by Active Days (Total: ' + '{{count}})', {count: tdata.total})} - initialChartState={{ + initialState={{ show3d: true, }} icons={renderDonutChartIcons} diff --git a/gsa/src/web/pages/nvts/dashboard/qoddisplay.js b/gsa/src/web/pages/nvts/dashboard/qoddisplay.js index 95bd4902d4..4c35e4ae1b 100644 --- a/gsa/src/web/pages/nvts/dashboard/qoddisplay.js +++ b/gsa/src/web/pages/nvts/dashboard/qoddisplay.js @@ -118,7 +118,7 @@ export class NvtsQodDisplay extends React.Component { dataTransform={transformQodData} title={({data: tdata}) => _('NVTs by QoD (Total: {{count}})', {count: tdata.total})} - initialChartState={{ + initialState={{ show3d: true, }} icons={renderDonutChartIcons} diff --git a/gsa/src/web/pages/nvts/dashboard/qodtypedisplay.js b/gsa/src/web/pages/nvts/dashboard/qodtypedisplay.js index f06cff9274..5d6449fe04 100644 --- a/gsa/src/web/pages/nvts/dashboard/qodtypedisplay.js +++ b/gsa/src/web/pages/nvts/dashboard/qodtypedisplay.js @@ -116,7 +116,7 @@ export class NvtsQodTypeDisplay extends React.Component { dataTransform={transformQodTypeData} title={({data: tdata}) => _('NVTs by QoD-Type (Total: {{count}})', {count: tdata.total})} - initialChartState={{ + initialState={{ show3d: true, }} icons={renderDonutChartIcons} diff --git a/gsa/src/web/pages/ovaldefs/dashboard/classdisplay.js b/gsa/src/web/pages/ovaldefs/dashboard/classdisplay.js index 622b592fbe..23f7fc522f 100644 --- a/gsa/src/web/pages/ovaldefs/dashboard/classdisplay.js +++ b/gsa/src/web/pages/ovaldefs/dashboard/classdisplay.js @@ -120,7 +120,7 @@ export class OvaldefClassDisplay extends React.Component { title={({data: tdata}) => _('OVAL Definitions by Class (Total: {{count}})', {count: tdata.total})} - initialChartState={{ + initialState={{ show3d: true, }} icons={renderDonutChartIcons} diff --git a/gsa/src/web/pages/overrides/dashboard/activedaysdisplay.js b/gsa/src/web/pages/overrides/dashboard/activedaysdisplay.js index ca6f24d865..7a8210a49c 100644 --- a/gsa/src/web/pages/overrides/dashboard/activedaysdisplay.js +++ b/gsa/src/web/pages/overrides/dashboard/activedaysdisplay.js @@ -169,7 +169,7 @@ export class OverridesActiveDaysDisplay extends React.Component { dataTransform={transformActiveDaysData} title={({data: tdata}) => _('Overrides by Active Days (Total: ' + '{{count}})', {count: tdata.total})} - initialChartState={{ + initialState={{ show3d: true, }} icons={renderDonutChartIcons} diff --git a/gsa/src/web/pages/secinfo/dashboard/typedisplay.js b/gsa/src/web/pages/secinfo/dashboard/typedisplay.js index 4a54bcbdf3..09236f2cb9 100644 --- a/gsa/src/web/pages/secinfo/dashboard/typedisplay.js +++ b/gsa/src/web/pages/secinfo/dashboard/typedisplay.js @@ -116,7 +116,7 @@ export class SecInfosTypeDisplay extends React.Component { title={({data: tdata}) => _('SecInfo Items by Type (Total: {{count}})', {count: tdata.total})} - initialChartState={{ + initialState={{ show3d: true, }} icons={renderDonutChartIcons} diff --git a/gsa/src/web/pages/tasks/dashboard/statusdisplay.js b/gsa/src/web/pages/tasks/dashboard/statusdisplay.js index 8f272cecbc..c683672a32 100644 --- a/gsa/src/web/pages/tasks/dashboard/statusdisplay.js +++ b/gsa/src/web/pages/tasks/dashboard/statusdisplay.js @@ -149,7 +149,7 @@ export class TasksStatusDisplay extends React.Component {