From bebe6cd95b7c5f4d567ea0f98940e5dae0739f82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Ricks?= Date: Mon, 15 Oct 2018 11:20:54 +0200 Subject: [PATCH 1/8] Add memoize-one package as dependency memoize-one caches a return value of a function depending on the passed parameters. --- gsa/package.json | 1 + gsa/yarn.lock | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/gsa/package.json b/gsa/package.json index 1244cb44f3..ee657229fa 100644 --- a/gsa/package.json +++ b/gsa/package.json @@ -43,6 +43,7 @@ "i18next": "^11.3.3", "i18next-xhr-backend": "1.5.1", "ical.js": "^1.2.2", + "memoize-one": "^4.0.2", "moment": "^2.22.2", "moment-timezone": "^0.5.21", "prop-types": "^15.6.2", diff --git a/gsa/yarn.lock b/gsa/yarn.lock index 2b903fbd23..d622b2b099 100644 --- a/gsa/yarn.lock +++ b/gsa/yarn.lock @@ -6509,6 +6509,11 @@ memoize-one@^3.1.1: resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-3.1.1.tgz#ef609811e3bc28970eac2884eece64d167830d17" integrity sha512-YqVh744GsMlZu6xkhGslPSqSurOv6P+kLN2J3ysBZfagLcL5FdRK/0UpgLoL8hwjjEvvAVkjJZyFP+1T6p1vgA== +memoize-one@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-4.0.2.tgz#3fb8db695aa14ab9c0f1644e1585a8806adc1aee" + integrity sha512-ucx2DmXTeZTsS4GPPUZCbULAN7kdPT1G+H49Y34JjbQ5ESc6OGhVxKvb1iKhr9v19ZB9OtnHwNnhUnNR/7Wteg== + memory-fs@^0.4.0, memory-fs@~0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552" From 12b26552dfe2437f533db2eadc883e17f13c7ee4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Ricks?= Date: Mon, 15 Oct 2018 11:23:12 +0200 Subject: [PATCH 2/8] Store display state in dashboard settings Put the display specific state in the dashboard settings at the redux store. --- gsa/src/web/components/dashboard/dashboard.js | 101 ++++++++++++------ .../dashboard/display/datadisplay.js | 47 ++++---- 2 files changed, 87 insertions(+), 61 deletions(-) diff --git a/gsa/src/web/components/dashboard/dashboard.js b/gsa/src/web/components/dashboard/dashboard.js index 2d32c45a1d..8c4de59388 100644 --- a/gsa/src/web/components/dashboard/dashboard.js +++ b/gsa/src/web/components/dashboard/dashboard.js @@ -23,6 +23,8 @@ import 'core-js/fn/array/find-index'; import 'core-js/fn/object/entries'; +import memoize from 'memoize-one'; + import React from 'react'; import {connect} from 'react-redux'; @@ -114,6 +116,8 @@ export class Dashboard extends React.Component { this.handleRowResize = this.handleRowResize.bind(this); this.handleUpdateDisplay = this.handleUpdateDisplay.bind(this); this.handleRemoveDisplay = this.handleRemoveDisplay.bind(this); + + this.getDisplaysById = memoize(rows => getDisplaysById(rows)); } componentDidMount() { @@ -140,37 +144,13 @@ export class Dashboard extends React.Component { handleItemsChange(gridItems = []) { const rows = this.getRows(); - const displaysById = getDisplaysById(rows); + const displaysById = this.getDisplaysById(rows); this.updateRows(convertGridItemsToDisplays(gridItems, displaysById)); } handleUpdateDisplay(id, props) { - const rows = this.getRows(); - - const rowIndex = rows.findIndex( - row => row.items.some(item => item.id === id)); - - const row = rows[rowIndex]; - - const rowItems = [ - ...row.items, - ]; - - const displayIndex = rowItems.findIndex(i => i.id === id); - - rowItems[displayIndex] = { - ...rowItems[displayIndex], - ...props, - }; - - const newRows = [...rows]; - newRows[rowIndex] = { - ...row, - rows: rowItems, - }; - - this.updateRows(newRows); + this.updateDisplay(id, props); } handleRemoveDisplay(id) { @@ -188,18 +168,15 @@ export class Dashboard extends React.Component { const newRows = [ ...rows, ]; - newRows[rowIndex] = { + const newRow = { ...row, height, }; + newRows[rowIndex] = newRow; this.updateRows(newRows); } - getRows(defaultRows) { - return getRows(this.props.settings, defaultRows); - } - handleInteraction() { const {onInteraction} = this.props; @@ -208,6 +185,63 @@ export class Dashboard extends React.Component { } } + handleSetDisplayState(id, stateFunc) { + const currentState = this.getDisplayState(id); + const newState = stateFunc(currentState); + + this.updateDisplayState(id, { + ...currentState, + ...newState, + }); + }; + + getRows(defaultRows) { + return getRows(this.props.settings, defaultRows); + } + + getDisplayState(id) { + const rows = this.getRows(); + const displaysById = this.getDisplaysById(rows); + const display = displaysById[id]; + return isDefined(display) ? display.state : undefined; + } + + updateDisplayState(id, state) { + this.updateDisplay(id, {state}); + } + + updateDisplay(id, props) { + const rows = this.getRows(); + + const rowIndex = rows.findIndex( + row => row.items.some(item => item.id === id)); + + const row = rows[rowIndex]; + + const rowItems = [ + ...row.items, + ]; + + const displayIndex = rowItems.findIndex(i => i.id === id); + + const newDisplay = { + ...rowItems[displayIndex], + ...props, + }; + + rowItems[displayIndex] = newDisplay; + + const newRows = [...rows]; + const newRow = { + ...row, + items: rowItems, + }; + + newRows[rowIndex] = newRow; + + this.updateRows(newRows); + } + updateRows(rows) { this.save({rows}); } @@ -245,7 +279,7 @@ export class Dashboard extends React.Component { ); } - const displaysById = getDisplaysById(rows); + const displaysById = this.getDisplaysById(rows); const getDisplayComponent = displayId => this.components[displayId]; const getDisplaySettings = id => displaysById[id]; @@ -273,6 +307,7 @@ export class Dashboard extends React.Component { }) => { const {displayId, ...displayProps} = getDisplaySettings(id); const Component = getDisplayComponent(displayId); + const state = this.getDisplayState(id); return ( this.handleSetDisplayState(id, stateFunc)} onFilterIdChanged={ filterId => this.handleUpdateDisplay(id, {filterId})} onInteractive={this.props.onInteraction} diff --git a/gsa/src/web/components/dashboard/display/datadisplay.js b/gsa/src/web/components/dashboard/display/datadisplay.js index aaa97c04ff..c3703a1d61 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, isFunction} from 'gmp/utils/identity'; +import {isDefined} from 'gmp/utils/identity'; import {excludeObjectProps} from 'gmp/utils/object'; import IconDivider from 'web/components/layout/icondivider'; @@ -125,15 +125,11 @@ class DataDisplay extends React.Component { data, originalData: this.props.data, title: this.props.title({data, id: this.props.id}), - childState: { - showLegend: true, - ...this.props.initialState, - }, }; this.handleDownloadSvg = this.handleDownloadSvg.bind(this); this.handleDownloadCsv = this.handleDownloadCsv.bind(this); - this.handleSetChildState = this.setChildState.bind(this); + this.handleSetState = this.handleSetState.bind(this); } static getDerivedStateFromProps(nextProps, prevState) { @@ -171,7 +167,7 @@ class DataDisplay extends React.Component { nextProps.width !== this.props.width || nextState.data !== this.state.data || nextProps.showFilterString !== this.props.showFilterString || - nextState.childState !== this.state.childState || + nextProps.state !== this.props.state || this.hasFilterChanged(nextProps); } @@ -215,23 +211,12 @@ class DataDisplay extends React.Component { } } - setChildState(state) { - if (isFunction(state)) { - this.setState(({childState}) => ({ - childState: { - ...childState, - ...state(childState), - }, - })); - } - else { - this.setState(({childState}) => ({ - childState: { - ...childState, - ...state, - }, - })); - } + getCurrentState(state = this.props.state) { + return { + showLegend: true, + ...this.props.initialState, + ...state, + }; } handleDownloadSvg() { @@ -274,9 +259,12 @@ class DataDisplay extends React.Component { download.click(); } + handleSetState(stateFunc) { + return this.props.setState(state => stateFunc(this.getCurrentState(state))); + } + render() { const { - childState, data: transformedData, title, } = this.state; @@ -316,6 +304,7 @@ class DataDisplay extends React.Component { } const showContent = height > 0 && width > 0; // > 0 also checks for null, undefined and null + const state = this.getCurrentState(); return ( } {icons && icons({ - state: childState, - setState: this.handleSetChildState, + state, + setState: this.handleSetState, showFilterSelection, showCsvDownload, showSvgDownload, From 1fad795a7b2ebe296d669ae114b5dc78a1de37cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Ricks?= Date: Mon, 15 Oct 2018 15:32:41 +0200 Subject: [PATCH 3/8] Forward settings to Dashboard and DashboardControls Forward the settings passed to StartDashboard to the Dashboard and DashboardControls. --- gsa/src/web/pages/start/dashboard.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/gsa/src/web/pages/start/dashboard.js b/gsa/src/web/pages/start/dashboard.js index 507390d4ae..6649082d85 100644 --- a/gsa/src/web/pages/start/dashboard.js +++ b/gsa/src/web/pages/start/dashboard.js @@ -70,6 +70,7 @@ const StartDashboard = ({ id, loadSettings, saveSettings, + settings, onInteraction, onNewDisplay, onResetDashboard, @@ -78,6 +79,7 @@ const StartDashboard = ({ Date: Mon, 15 Oct 2018 15:34:07 +0200 Subject: [PATCH 4/8] Allow to export DashboardSetting class directly --- gsa/src/web/store/dashboard/settings/selectors.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gsa/src/web/store/dashboard/settings/selectors.js b/gsa/src/web/store/dashboard/settings/selectors.js index 565fd1df04..0e54e24d1a 100644 --- a/gsa/src/web/store/dashboard/settings/selectors.js +++ b/gsa/src/web/store/dashboard/settings/selectors.js @@ -22,7 +22,7 @@ */ import {isDefined} from 'gmp/utils/identity'; -class DashboardSetting { +export class DashboardSetting { constructor(rootState) { this.state = rootState; From be798ce2763f54a2fa4b4c25412e16d9259bf32f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Ricks?= Date: Mon, 15 Oct 2018 15:40:27 +0200 Subject: [PATCH 5/8] Update main Dashboard Rework main Dashboard to abstract settings and dashboard settings. --- gsa/src/web/pages/start/page.js | 237 +++++++++++++++----------------- 1 file changed, 112 insertions(+), 125 deletions(-) diff --git a/gsa/src/web/pages/start/page.js b/gsa/src/web/pages/start/page.js index 077490ac3a..900531c687 100644 --- a/gsa/src/web/pages/start/page.js +++ b/gsa/src/web/pages/start/page.js @@ -24,6 +24,8 @@ import React from 'react'; import uuid from 'uuid/v4'; +import memoize from 'memoize-one'; + import styled from 'styled-components'; import {connect} from 'react-redux'; @@ -39,8 +41,11 @@ import withGmp from 'web/utils/withGmp'; import { loadSettings, saveSettings, + setDashboardSettingDefaults, } from 'web/store/dashboard/settings/actions'; -import getDashboardSettings from 'web/store/dashboard/settings/selectors'; +import getDashboardSettings, { + DashboardSetting, +} from 'web/store/dashboard/settings/selectors'; import {renewSessionTimeout} from 'web/store/usersettings/actions'; import CloseButton from 'web/components/dialog/closebutton'; @@ -75,6 +80,7 @@ import NewDashboardDialog, {DEFAULT_DISPLAYS} from './newdashboarddialog'; const DASHBOARD_ID = 'd97eca9f-0386-4e5d-88f2-0ed7f60c0646'; const OVERVIEW_DASHBOARD_ID = '84fbe9f5-8ad4-43f0-9712-850182abb003'; +const DEFAULT_OVERVIEW_DISPLAYS = convertDefaultDisplays(DEFAULT_DISPLAYS); const getDefaults = () => ({ dashboards: [ @@ -82,12 +88,10 @@ const getDefaults = () => ({ ], byId: { [OVERVIEW_DASHBOARD_ID]: { + ...DEFAULT_OVERVIEW_DISPLAYS, title: _('Overview'), }, }, - defaults: { - [OVERVIEW_DASHBOARD_ID]: convertDefaultDisplays(DEFAULT_DISPLAYS), - }, }); const DEFAULT_TAB = 0; @@ -134,33 +138,35 @@ class StartPage extends React.Component { this.handleResetDashboards = this.handleResetDashboards.bind(this); this.handleSetDefaultSettings = this.handleSetDefaultSettings.bind(this); + + this.getDashboardSelector = memoize(settings => + new DashboardSetting(settings)); } componentDidMount() { - this.props.loadSettings(DASHBOARD_ID); + const DEFAULTS = getDefaults(); + this.props.loadSettings(DASHBOARD_ID, DEFAULTS); } - saveSettings(settings) { - const {byId, defaults, dashboards} = this.props; - + saveSettings(newSettings) { this.props.saveSettings(DASHBOARD_ID, { - byId, - defaults, - dashboards, - ...settings, + ...this.props.settings, + ...newSettings, }); } handleRemoveDashboard(dashboardId) { - const {byId, dashboards, defaults = {}} = this.props; + const dashboards = this.getDashboards(); if (dashboards.length <= 1) { return; } + const {settings = {}} = this.props; + const {byId = {}, defaults = {}} = settings; + const byIdCopy = {...byId}; delete byIdCopy[dashboardId]; - const defaultsCopy = {...defaults}; delete defaultsCopy[dashboardId]; @@ -173,7 +179,6 @@ class StartPage extends React.Component { byId: byIdCopy, dashboards: dashboards.filter(id => id !== dashboardId), defaults: defaultsCopy, - removeDashboardId: undefined, }); } @@ -208,17 +213,7 @@ class StartPage extends React.Component { } handleSaveDashboardSettings(dashboardId, settings) { - const {byId} = this.props; - - this.saveSettings({ - byId: { - ...byId, - [dashboardId]: { - ...byId[dashboardId], - ...settings, - }, - }, - }); + this.updateDashboardSettings(dashboardId, settings); } handleLoadDashboardSettings() { @@ -227,57 +222,31 @@ class StartPage extends React.Component { } handleSetDefaultSettings(dashboardId, defaultSettings) { - const {defaults = {}} = this.props; - - this.saveSettings({ - defaults: { - ...defaults, - [dashboardId]: { - ...defaults[dashboardId], - ...defaultSettings, - }, - }, - }); + this.updateDashboardDefaults(dashboardId, defaultSettings); } handleResetDashboard(dashboardId) { - const {byId, defaults = {}} = this.props; - - this.saveSettings({ - byId: { - ...byId, - [dashboardId]: { - ...byId[dashboardId], - ...defaults[dashboardId], - }, - }, - }); + const settings = this.getDashboardDefaults(dashboardId); + this.updateDashboardSettings(dashboardId, settings); } - handleAddNewDisplay(dashboardId, displayId) { + handleAddNewDisplay(oldSettings, dashboardId, displayId) { if (!isDefined(displayId) || !isDefined(dashboardId)) { return; } - const {byId} = this.props; - const settings = byId[dashboardId]; - - if (!canAddDisplay(settings)) { + if (!canAddDisplay(oldSettings)) { return; } - const newSettings = addDisplayToSettings(settings, displayId); - - this.saveSettings({ - byId: { - ...byId, - [dashboardId]: newSettings, - }, - }); + const newSettings = addDisplayToSettings(oldSettings, displayId); + this.updateDashboardSettings(dashboardId, newSettings); } handleAddNewDashboard({title, defaultDisplays = DEFAULT_DISPLAYS}) { - const {byId, dashboards, defaults = {}} = this.props; + const {settings = {}} = this.props; + const {byId = {}} = settings; + const dashboards = this.getDashboards(); const id = uuid(); @@ -286,7 +255,7 @@ class StartPage extends React.Component { title, }; - const settings = { + const newSettings = { dashboards: [ ...dashboards, id, @@ -295,13 +264,9 @@ class StartPage extends React.Component { ...byId, [id]: newDashboardSetting, }, - defaults: { - ...defaults, - [id]: newDashboardSetting, - }, }; - this.saveSettings(settings); + this.saveSettings(newSettings); this.closeNewDashboardDialog(); @@ -313,21 +278,74 @@ class StartPage extends React.Component { // reset all dashboards // currently not assigned to a handler - const {byId, defaults} = this.props; - const DEFAULTS = getDefaults(); + // const {byId, defaults} = this.props; + // const DEFAULTS = getDefaults(); + + // this.saveSettings({ + // ...DEFAULTS, + // byId: { + // ...byId, + // [OVERVIEW_DASHBOARD_ID]: { + // ...DEFAULTS.byId[OVERVIEW_DASHBOARD_ID], + // ...defaults[OVERVIEW_DASHBOARD_ID], + // }, + // }, + // }); + } + + updateDashboardSettings(dashboardId, newSettings) { + const {byId = {}} = this.props.settings; + const oldSettings = this.getDashboardSettings(dashboardId); this.saveSettings({ - ...DEFAULTS, byId: { ...byId, - [OVERVIEW_DASHBOARD_ID]: { - ...DEFAULTS.byId[OVERVIEW_DASHBOARD_ID], - ...defaults[OVERVIEW_DASHBOARD_ID], + [dashboardId]: { + ...oldSettings, + ...newSettings, }, }, }); } + updateDashboardDefaults(dashboardId, newDefaults) { + const {defaults = {}} = this.props.settings; + this.saveSettings({ + defaults: { + ...defaults, + [dashboardId]: newDefaults, + }, + }); + }; + + getIsLoading() { + const {settings = {}} = this.props; + return !!settings.isLoading; + } + + getDashboards() { + const {settings = {}} = this.props; + const {dashboards = [], byId = {}} = settings; + return dashboards.filter(id => isDefined(byId[id])); + } + + getDashboardSettings(dashboardId) { + const {settings = {}} = this.props; + const selector = this.getDashboardSelector(settings); + return selector.getById(dashboardId); + } + + getDashboardDefaults(dashboardId) { + const {settings = {}} = this.props; + const selector = this.getDashboardSelector(settings); + return selector.getDefaultsById(dashboardId); + } + + getDashboardTitle(dashboardId) { + const dashboardSettings = this.getDashboardSettings(dashboardId); + return dashboardSettings.title; + } + render() { const { activeTab, @@ -336,16 +354,8 @@ class StartPage extends React.Component { showConfirmRemoveDialog, } = this.state; - const { - byId = {}, - isLoading = false, - } = this.props; - - let { - dashboards = [], - } = this.props; - - dashboards = dashboards.filter(id => isDefined(byId[id])); + const dashboards = this.getDashboards(); + const isLoading = this.getIsLoading(); const canAdd = dashboards.length < MAX_DASHBOARDS; return ( @@ -368,8 +378,7 @@ class StartPage extends React.Component { onActivateTab={this.handleActivateTab} > {dashboards.map(id => { - const dashboard = byId[id]; - const {title} = dashboard; + const title = this.getDashboardTitle(id); return ( {dashboards.map(id => { - const dashboard = byId[id]; - const {rows, title, ...settings} = dashboard; + const settings = this.getDashboardSettings(id); return ( {({notify}) => ( @@ -463,50 +469,29 @@ class StartPage extends React.Component { } StartPage.propTypes = { - byId: PropTypes.object, - dashboards: PropTypes.array, - defaults: PropTypes.object, + error: PropTypes.toString, isLoading: PropTypes.bool, loadSettings: PropTypes.func.isRequired, renewSessionTimeout: PropTypes.func.isRequired, saveSettings: PropTypes.func.isRequired, + settings: PropTypes.shape({ + byId: PropTypes.object.isRequired, + dashboards: PropTypes.arrayOf(PropTypes.string).isRequired, + defaults: PropTypes.object.isRequired, + }), }; const mapStateToProps = rootState => { const settingsSelector = getDashboardSettings(rootState); const settings = settingsSelector.getById(DASHBOARD_ID); - const {rows} = settings || {}; - let {byId, defaults, dashboards} = settings || {}; - const DEFAULTS = getDefaults(); - - if (isDefined(rows)) { - byId = { - [OVERVIEW_DASHBOARD_ID]: { - ...DEFAULTS.byId[OVERVIEW_DASHBOARD_ID], - rows, - }, - }; - dashboards = [OVERVIEW_DASHBOARD_ID]; - } + const isLoading = settingsSelector.getIsLoading(DASHBOARD_ID); + const error = settingsSelector.getError(DASHBOARD_ID); - const props = { - isLoading: settingsSelector.getIsLoading(DASHBOARD_ID), - ...DEFAULTS, - byId: { - ...DEFAULTS.byId, - ...byId, - }, - defaults: { - ...DEFAULTS.defaults, - ...defaults, - }, + return { + error, + isLoading, + settings, }; - - if (isDefined(dashboards)) { - props.dashboards = dashboards; - } - - return props; }; const mapDispatchToProps = (dispatch, {gmp}) => ({ @@ -515,6 +500,8 @@ const mapDispatchToProps = (dispatch, {gmp}) => ({ saveSettings: (id, settings) => dispatch(saveSettings(gmp)(id, settings)), renewSessionTimeout: () => dispatch(renewSessionTimeout(gmp)()), + setDefaultSettings: (id, settings) => + dispatch(setDashboardSettingDefaults(id, settings)), }); export default compose( From c6c7314d36c956107179940fb56d5bee8a696a9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Ricks?= Date: Mon, 15 Oct 2018 16:21:24 +0200 Subject: [PATCH 6/8] Fix rendering of LineChart The line chart must re-render if with, data and height has changed. After the state has been calculated the re-render must be allowed in shouldComponentUpdate by checking if the data in the state has changed since last render. The state calculation in LineChart is far from beeing optimal. Maybe all charts could be simplified by extracting the width re-calculation when a legend is displayed into another separated reusable component. --- gsa/src/web/components/chart/line.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/gsa/src/web/components/chart/line.js b/gsa/src/web/components/chart/line.js index 0cc777241b..76a0461281 100644 --- a/gsa/src/web/components/chart/line.js +++ b/gsa/src/web/components/chart/line.js @@ -189,6 +189,7 @@ class LineChart extends React.Component { nextState.infoX !== this.state.infoX || nextState.mouseX !== this.state.mouseX || nextState.mouseY !== this.state.mouseY || + nextState.data !== this.state.data || nextState.displayInfo !== this.state.displayInfo; } @@ -301,7 +302,10 @@ class LineChart extends React.Component { update() { const width = this.getWidth(); - if (width !== this.state.width) { + if (width !== this.state.width || + this.props.data !== this.state.data || + this.props.height !== this.state.height) { + // update state if width, data or height has changed since last render this.setState(this.stateFromWidth(width)); } } @@ -361,6 +365,7 @@ class LineChart extends React.Component { .nice(); return { + data, xScale, yScale, y2Scale, From 422191c50c151954c154c3cad2c05631ca63d41f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Ricks?= Date: Mon, 15 Oct 2018 16:45:43 +0200 Subject: [PATCH 7/8] Set isLoading to false by default for dashboards at main page The settings are loaded via the main dashboard so isLoading is always false for these dashboards. --- gsa/src/web/pages/start/dashboard.js | 1 + 1 file changed, 1 insertion(+) diff --git a/gsa/src/web/pages/start/dashboard.js b/gsa/src/web/pages/start/dashboard.js index 6649082d85..58e5ba42cc 100644 --- a/gsa/src/web/pages/start/dashboard.js +++ b/gsa/src/web/pages/start/dashboard.js @@ -91,6 +91,7 @@ const StartDashboard = ({ Date: Mon, 15 Oct 2018 16:46:39 +0200 Subject: [PATCH 8/8] Pass the correct isLoading variable to main dashboard render The store layout is a bit confusing the for main dashboard because it's so complex. Fix getting the isLoading indicator. --- gsa/src/web/pages/start/page.js | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/gsa/src/web/pages/start/page.js b/gsa/src/web/pages/start/page.js index 900531c687..2fe14ad139 100644 --- a/gsa/src/web/pages/start/page.js +++ b/gsa/src/web/pages/start/page.js @@ -318,11 +318,6 @@ class StartPage extends React.Component { }); }; - getIsLoading() { - const {settings = {}} = this.props; - return !!settings.isLoading; - } - getDashboards() { const {settings = {}} = this.props; const {dashboards = [], byId = {}} = settings; @@ -347,6 +342,9 @@ class StartPage extends React.Component { } render() { + const { + isLoading, + } = this.props; const { activeTab, removeDashboardId, @@ -355,7 +353,6 @@ class StartPage extends React.Component { } = this.state; const dashboards = this.getDashboards(); - const isLoading = this.getIsLoading(); const canAdd = dashboards.length < MAX_DASHBOARDS; return (