From ac1859510b09ced2bb7ddb067dd30b67a2884e41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Ricks?= Date: Tue, 25 Sep 2018 11:39:05 +0200 Subject: [PATCH 01/12] Remove default dashboard settings from store If a dashboard at the main dashboard is removed also remove the default settings for this dashboard. --- gsa/src/web/pages/start/page.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/gsa/src/web/pages/start/page.js b/gsa/src/web/pages/start/page.js index 0724c79d73..909d638bc0 100644 --- a/gsa/src/web/pages/start/page.js +++ b/gsa/src/web/pages/start/page.js @@ -144,15 +144,17 @@ class StartPage extends React.Component { } handleRemoveDashboard(dashboardId) { - const {byId, dashboards} = this.props; + const {byId, dashboards, defaults = {}} = this.props; if (dashboards.length <= 1) { return; } - const copyById = {...byId}; + const byIdCopy = {...byId}; + delete byIdCopy[dashboardId]; - delete copyById[dashboardId]; + const defaultsCopy = {...defaults}; + delete defaultsCopy[dashboardId]; this.setState({ showConfirmRemoveDialog: false, @@ -160,8 +162,9 @@ class StartPage extends React.Component { }); this.saveSettings({ - byId: copyById, + byId: byIdCopy, dashboards: dashboards.filter(id => id !== dashboardId), + defaults: defaultsCopy, removeDashboardId: undefined, }); } From f2565f3c5aff7097a0972e07772ad027e70482e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Ricks?= Date: Tue, 25 Sep 2018 12:03:36 +0200 Subject: [PATCH 02/12] Export sortable grid helper functions to utils module --- gsa/CMakeLists.txt | 1 + gsa/src/web/components/dashboard/dashboard.js | 8 +-- gsa/src/web/components/sortable/grid.js | 43 ++++----------- gsa/src/web/components/sortable/utils.js | 54 +++++++++++++++++++ .../web/store/dashboard/settings/actions.js | 2 +- 5 files changed, 70 insertions(+), 38 deletions(-) create mode 100644 gsa/src/web/components/sortable/utils.js diff --git a/gsa/CMakeLists.txt b/gsa/CMakeLists.txt index 52f10964cb..c4aaba862b 100644 --- a/gsa/CMakeLists.txt +++ b/gsa/CMakeLists.txt @@ -320,6 +320,7 @@ set (GSA_JS_SRC_FILES ${GSA_SRC_DIR}/src/web/components/sortable/item.js ${GSA_SRC_DIR}/src/web/components/sortable/resizer.js ${GSA_SRC_DIR}/src/web/components/sortable/row.js + ${GSA_SRC_DIR}/src/web/components/sortable/utils.js ${GSA_SRC_DIR}/src/web/components/structure/footer.js ${GSA_SRC_DIR}/src/web/components/structure/header.js ${GSA_SRC_DIR}/src/web/components/structure/main.js diff --git a/gsa/src/web/components/dashboard/dashboard.js b/gsa/src/web/components/dashboard/dashboard.js index a3af1e57f8..00fc9de2f4 100644 --- a/gsa/src/web/components/dashboard/dashboard.js +++ b/gsa/src/web/components/dashboard/dashboard.js @@ -45,11 +45,13 @@ import DashboardSettings from 'web/store/dashboard/settings/selectors'; import Loading from 'web/components/loading/loading'; import Grid, { - createRow, - createItem, itemsPropType, - DEFAULT_ROW_HEIGHT, } from 'web/components/sortable/grid'; +import { + DEFAULT_ROW_HEIGHT, + createRow, + createItem, +} from 'web/components/sortable/utils'; import PropTypes from 'web/utils/proptypes'; import withGmp from 'web/utils/withGmp'; diff --git a/gsa/src/web/components/sortable/grid.js b/gsa/src/web/components/sortable/grid.js index cc1b9ae4e3..95a0261365 100644 --- a/gsa/src/web/components/sortable/grid.js +++ b/gsa/src/web/components/sortable/grid.js @@ -26,52 +26,27 @@ import 'core-js/library/fn/array/find'; import React from 'react'; -import uuid from 'uuid/v4'; - import {DragDropContext} from 'react-beautiful-dnd'; import {isDefined} from 'gmp/utils/identity'; -import PropTypes from '../../utils/proptypes.js'; +import AutoSize from 'web/components/layout/autosize'; +import Layout from 'web/components/layout/layout'; -import Layout from '../layout/layout'; +import PropTypes from 'web/utils/proptypes'; import EmptyRow from './emptyrow'; import Item, {GRID_ITEM_MARGIN} from './item'; import Row from './row'; -import AutoSize from '../layout/autosize.js'; +import { + updateRow, + removeItem, + createRow, + DEFAULT_ROW_HEIGHT, +} from './utils'; const findRowIndex = (rows, rowid) => rows.findIndex(row => row.id === rowid); -export const DEFAULT_ROW_HEIGHT = 250; - -export const createRow = (items, height = DEFAULT_ROW_HEIGHT) => ({ - id: uuid(), - height, - items, -}); - -export const createItem = props => { - const id = uuid(); - - return { - id, - ...props, - }; -}; - -export const removeItem = (rows, itemId) => rows.map(row => ({ - ...row, - items: row.items.filter(item => item.id !== itemId), -})).filter(row => row.items.length > 0); - -const updateRow = (row, data) => { - return { - ...row, - ...data, - }; -}; - const itemPropType = PropTypes.shape({ id: PropTypes.string.isRequired, }); diff --git a/gsa/src/web/components/sortable/utils.js b/gsa/src/web/components/sortable/utils.js new file mode 100644 index 0000000000..11e2c37249 --- /dev/null +++ b/gsa/src/web/components/sortable/utils.js @@ -0,0 +1,54 @@ +/* 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 uuid from 'uuid/v4'; + +export const DEFAULT_ROW_HEIGHT = 250; + +export const createRow = (items, height = DEFAULT_ROW_HEIGHT) => ({ + id: uuid(), + height, + items, +}); + +export const createItem = props => { + const id = uuid(); + + return { + id, + ...props, + }; +}; + +export const removeItem = (rows, itemId) => rows.map(row => ({ + ...row, + items: row.items.filter(item => item.id !== itemId), +})).filter(row => row.items.length > 0); + +export const updateRow = (row, data) => { + return { + ...row, + ...data, + }; +}; + +// vim: set ts=2 sw=2 tw=80: diff --git a/gsa/src/web/store/dashboard/settings/actions.js b/gsa/src/web/store/dashboard/settings/actions.js index 5b7901ba87..f75e7b5394 100644 --- a/gsa/src/web/store/dashboard/settings/actions.js +++ b/gsa/src/web/store/dashboard/settings/actions.js @@ -24,7 +24,7 @@ import 'core-js/fn/object/entries'; import {isDefined, isArray} from 'gmp/utils/identity'; -import {createRow, createItem} from 'web/components/sortable/grid'; +import {createRow, createItem} from 'web/components/sortable/utils'; import getDashboardSettings from './selectors'; From e8b1d29f0a6dbe3a99bf2ed62bef11dbb7a53825 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Ricks?= Date: Tue, 25 Sep 2018 12:06:33 +0200 Subject: [PATCH 03/12] Move convertDefaultContent function to sortable utils --- gsa/src/web/components/dashboard/dashboard.js | 7 +------ gsa/src/web/components/sortable/utils.js | 4 ++++ 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/gsa/src/web/components/dashboard/dashboard.js b/gsa/src/web/components/dashboard/dashboard.js index 00fc9de2f4..5fa34e7b15 100644 --- a/gsa/src/web/components/dashboard/dashboard.js +++ b/gsa/src/web/components/dashboard/dashboard.js @@ -49,8 +49,7 @@ import Grid, { } from 'web/components/sortable/grid'; import { DEFAULT_ROW_HEIGHT, - createRow, - createItem, + convertDefaultContent, } from 'web/components/sortable/utils'; import PropTypes from 'web/utils/proptypes'; @@ -85,10 +84,6 @@ const RowPlaceHolder = styled.div` align-items: center; `; -const convertDefaultContent = defaultContent => - defaultContent.map(row => createRow( - row.map(item => createItem({name: item})))); - const filterItems = (items, allowed) => items.map(row => { const {items: rowItems = []} = row; return { diff --git a/gsa/src/web/components/sortable/utils.js b/gsa/src/web/components/sortable/utils.js index 11e2c37249..31f8d42f59 100644 --- a/gsa/src/web/components/sortable/utils.js +++ b/gsa/src/web/components/sortable/utils.js @@ -51,4 +51,8 @@ export const updateRow = (row, data) => { }; }; +export const convertDefaultContent = defaultContent => + defaultContent.map(row => createRow( + row.map(item => createItem({name: item})))); + // vim: set ts=2 sw=2 tw=80: From d53deb887bc05757739dab05251a5af3513d7757 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Ricks?= Date: Tue, 25 Sep 2018 15:25:19 +0200 Subject: [PATCH 04/12] Allow easier testing of sortable helper functions Allow to pass a id generator function to createRow, createItem and convertDefaultContent functions. --- gsa/src/web/components/sortable/utils.js | 25 ++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/gsa/src/web/components/sortable/utils.js b/gsa/src/web/components/sortable/utils.js index 31f8d42f59..c1362f6d26 100644 --- a/gsa/src/web/components/sortable/utils.js +++ b/gsa/src/web/components/sortable/utils.js @@ -24,14 +24,15 @@ import uuid from 'uuid/v4'; export const DEFAULT_ROW_HEIGHT = 250; -export const createRow = (items, height = DEFAULT_ROW_HEIGHT) => ({ - id: uuid(), +export const createRow = (items, height = DEFAULT_ROW_HEIGHT, + uuidFunc = uuid) => ({ + id: uuidFunc(), height, items, }); -export const createItem = props => { - const id = uuid(); +export const createItem = (props, uuidFunc = uuid) => { + const id = uuidFunc(); return { id, @@ -44,15 +45,15 @@ export const removeItem = (rows, itemId) => rows.map(row => ({ items: row.items.filter(item => item.id !== itemId), })).filter(row => row.items.length > 0); -export const updateRow = (row, data) => { - return { - ...row, - ...data, - }; -}; +export const updateRow = (row, data) => ({ + ...row, + ...data, +}); -export const convertDefaultContent = defaultContent => +export const convertDefaultContent = (defaultContent = [], uuidFunc = uuid) => defaultContent.map(row => createRow( - row.map(item => createItem({name: item})))); + row.map(item => createItem({name: item}, uuidFunc)), undefined, uuidFunc + )); + // vim: set ts=2 sw=2 tw=80: From dcdccedf7c274185ee6f0b7668094c3e9bb2a891 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Ricks?= Date: Tue, 25 Sep 2018 15:26:37 +0200 Subject: [PATCH 05/12] Add test for sortable helper functions --- .../components/sortable/__tests__/utils.js | 201 ++++++++++++++++++ 1 file changed, 201 insertions(+) create mode 100644 gsa/src/web/components/sortable/__tests__/utils.js diff --git a/gsa/src/web/components/sortable/__tests__/utils.js b/gsa/src/web/components/sortable/__tests__/utils.js new file mode 100644 index 0000000000..cbe1d4f559 --- /dev/null +++ b/gsa/src/web/components/sortable/__tests__/utils.js @@ -0,0 +1,201 @@ +/* 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 { + convertDefaultContent, + createItem, + createRow, + removeItem, + updateRow, + DEFAULT_ROW_HEIGHT, +} from '../utils'; + +describe('createItem tests', () => { + + test('should create a new item with empty props', () => { + const uuid = jest.fn().mockReturnValue(1); + expect(createItem(undefined, uuid)).toEqual({ + id: 1, + }); + expect(uuid).toHaveBeenCalled(); + }); + + test('should create a new item with props', () => { + const uuid = jest.fn().mockReturnValue(1); + expect(createItem({foo: 'bar'}, uuid)).toEqual({ + id: 1, + foo: 'bar', + }); + expect(uuid).toHaveBeenCalled(); + }); + +}); + +describe('createRow tests', () => { + + test('should create row with default height', () => { + const uuid = jest.fn().mockReturnValue(1); + expect(createRow(['foo', 'bar'], undefined, uuid)).toEqual({ + id: 1, + items: ['foo', 'bar'], + height: DEFAULT_ROW_HEIGHT, + }); + expect(uuid).toHaveBeenCalled(); + }); + + test('should create row with height', () => { + const uuid = jest.fn().mockReturnValue(1); + expect(createRow(['foo', 'bar'], 100, uuid)).toEqual({ + id: 1, + items: ['foo', 'bar'], + height: 100, + }); + expect(uuid).toHaveBeenCalled(); + }); + +}); + +describe('removeItem tests', () => { + + test('should filter empty rows', () => { + const rows = [{ + items: [], + }, { + items: [{ + id: 1, + }], + }]; + + const filtered = removeItem(rows); + expect(filtered.length).toEqual(1); + expect(filtered).toEqual([{ + items: [{ + id: 1, + }], + }]); + }); + + test('should remove item with id', () => { + const rows = [{ + items: [{ + id: 1, + }, { + id: 2, + }], + }, { + items: [{ + id: 3, + }], + }]; + + const filtered = removeItem(rows, 1); + expect(filtered.length).toEqual(2); + expect(filtered).toEqual([{ + items: [{ + id: 2, + }], + }, { + items: [{ + id: 3, + }], + }]); + }); + +}); + +describe('updateRow tests', () => { + + test('should return a shallow copy', () => { + const row = { + items: [{ + id: 1, + }], + }; + + const updated = updateRow(row); + expect(updated).not.toBe(row); + expect(updated).toEqual(row); + }); + + test('should return empty object', () => { + expect(updateRow()).toEqual({}); + }); + + test('should update row', () => { + const row = { + items: [{ + id: 1, + }], + }; + + const updated = updateRow(row, {foo: 'bar'}); + expect(updated).not.toBe(row); + expect(updated).toEqual({ + items: [{ + id: 1, + }], + foo: 'bar', + }); + }); + +}); + +describe('convertDefaultContent test', () => { + + test('should return empty array', () => { + expect(convertDefaultContent()).toEqual([]); + }); + + test('should convert array to rows', () => { + let i = 1; + const uuid = jest.fn().mockImplementation(() => i++); + + const rows = [[ + 'foo', + 'bar', + ], [ + 'lorem', + ]]; + + expect(convertDefaultContent(rows, uuid)).toEqual([{ + height: DEFAULT_ROW_HEIGHT, + id: 3, + items: [{ + id: 1, + name: 'foo', + }, { + id: 2, + name: 'bar', + }], + }, { + height: DEFAULT_ROW_HEIGHT, + id: 5, + items: [{ + id: 4, + name: 'lorem', + }], + }]); + }); + +}); + +// vim: set ts=2 sw=2 tw=80: From 83a3a8c1691cabc9bf7f19fdbf04b5c365bd1526 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Ricks?= Date: Tue, 25 Sep 2018 15:29:53 +0200 Subject: [PATCH 06/12] Move DEFAULT_DISPLAYS to NewDashboardDialog module --- gsa/src/web/pages/start/dashboard.js | 15 +-------------- gsa/src/web/pages/start/newdashboarddialog.js | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/gsa/src/web/pages/start/dashboard.js b/gsa/src/web/pages/start/dashboard.js index 124203f38e..ced1ac06f8 100644 --- a/gsa/src/web/pages/start/dashboard.js +++ b/gsa/src/web/pages/start/dashboard.js @@ -31,11 +31,6 @@ import {DashboardControls} from 'web/components/dashboard/controls'; import Layout from 'web/components/layout/layout'; -import {TasksSeverityDisplay} from '../tasks/dashboard/severityclassdisplay'; -import {CvesCreatedDisplay} from '../cves/dashboard/createddisplay'; -import {TasksStatusDisplay} from '../tasks/dashboard/statusdisplay'; -import {NvtsSeverityClassDisplay} from '../nvts/dashboard/severityclassdisplay'; - import {TASKS_DISPLAYS} from '../tasks/dashboard'; import {REPORTS_DISPLAYS} from '../reports/dashboard'; import {RESULTS_DISPLAYS} from '../results/dashboard'; @@ -52,15 +47,7 @@ import {CPES_DISPLAYS} from '../cpes/dashboard'; import {DFNCERT_DISPLAYS} from '../dfncert/dashboard'; import {SECINFO_DISPLAYS} from '../secinfo/dashboard'; -const DEFAULT_DISPLAYS = [ - [ - TasksSeverityDisplay.displayId, - TasksStatusDisplay.displayId, - ], [ - CvesCreatedDisplay.displayId, - NvtsSeverityClassDisplay.displayId, - ], -]; +import {DEFAULT_DISPLAYS} from './newdashboarddialog'; const ALL_DISPLAYS = [ ...TASKS_DISPLAYS, diff --git a/gsa/src/web/pages/start/newdashboarddialog.js b/gsa/src/web/pages/start/newdashboarddialog.js index 505001ad04..3663805dc0 100644 --- a/gsa/src/web/pages/start/newdashboarddialog.js +++ b/gsa/src/web/pages/start/newdashboarddialog.js @@ -31,8 +31,25 @@ import SaveDialog from 'web/components/dialog/savedialog'; import FormGroup from 'web/components/form/formgroup'; import TextField from 'web/components/form/textfield'; +/* eslint-disable max-len */ +import {CvesCreatedDisplay} from 'web/pages/cves/dashboard/createddisplay'; +import {NvtsSeverityClassDisplay} from 'web/pages/nvts/dashboard/severityclassdisplay'; +import {TasksSeverityDisplay} from 'web/pages/tasks/dashboard/severityclassdisplay'; +import {TasksStatusDisplay} from 'web/pages/tasks/dashboard/statusdisplay'; +/* eslint-enable max-len */ + const MAX_TITLE_LENGTH = 50; +export const DEFAULT_DISPLAYS = [ + [ + TasksSeverityDisplay.displayId, + TasksStatusDisplay.displayId, + ], [ + CvesCreatedDisplay.displayId, + NvtsSeverityClassDisplay.displayId, + ], +]; + const NewDashboardDialog = ({ onClose, onSave, From 69df556b74737f2451fd698b7e4595a4b4f16ddb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Ricks?= Date: Tue, 25 Sep 2018 15:30:46 +0200 Subject: [PATCH 07/12] Put defaults for overview dashboard into default settings --- gsa/src/web/pages/start/page.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/gsa/src/web/pages/start/page.js b/gsa/src/web/pages/start/page.js index 909d638bc0..53c378d83e 100644 --- a/gsa/src/web/pages/start/page.js +++ b/gsa/src/web/pages/start/page.js @@ -58,6 +58,8 @@ import SubscriptionProvider from 'web/components/provider/subscriptionprovider'; import Section from 'web/components/section/section'; +import {convertDefaultContent} from 'web/components/sortable/utils'; + import Tab from 'web/components/tab/tab'; import TabLayout from 'web/components/tab/tablayout'; import TabList from 'web/components/tab/tablist'; @@ -67,7 +69,7 @@ import Tabs from 'web/components/tab/tabs'; import Dashboard from './dashboard'; import ConfirmRemoveDialog from './confirmremovedialog'; -import NewDashboardDialog from './newdashboarddialog'; +import NewDashboardDialog, {DEFAULT_DISPLAYS} from './newdashboarddialog'; const DASHBOARD_ID = 'd97eca9f-0386-4e5d-88f2-0ed7f60c0646'; const OVERVIEW_DASHBOARD_ID = '84fbe9f5-8ad4-43f0-9712-850182abb003'; @@ -81,6 +83,11 @@ const getDefaults = () => ({ title: _('Overview'), }, }, + defaults: { + [OVERVIEW_DASHBOARD_ID]: { + rows: convertDefaultContent(DEFAULT_DISPLAYS), + }, + }, }); const DEFAULT_TAB = 0; From e91e5164daa80906b37c6b50a091b51e3abb1e93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Ricks?= Date: Tue, 25 Sep 2018 15:32:26 +0200 Subject: [PATCH 08/12] Allow to pass default displays when creating new dashboard When creating a new dashboard at the main page allow to pass an array of default displays. --- gsa/src/web/pages/start/page.js | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/gsa/src/web/pages/start/page.js b/gsa/src/web/pages/start/page.js index 53c378d83e..144ef0ddbb 100644 --- a/gsa/src/web/pages/start/page.js +++ b/gsa/src/web/pages/start/page.js @@ -277,23 +277,33 @@ class StartPage extends React.Component { }); } - handleAddNewDashboard({title}) { - const {byId, dashboards} = this.props; + handleAddNewDashboard({title, defaultDisplays = DEFAULT_DISPLAYS}) { + const {byId, dashboards, defaults = {}} = this.props; const id = uuid(); - this.saveSettings({ + const rows = convertDefaultContent(defaultDisplays); + const newDashboardSetting = { + rows, + title, + }; + + const settings = { dashboards: [ ...dashboards, id, ], byId: { ...byId, - [id]: { - title, - }, + [id]: newDashboardSetting, }, - }); + defaults: { + ...defaults, + [id]: newDashboardSetting, + }, + }; + + this.saveSettings(settings); this.closeNewDashboardDialog(); From df62a4e423ac2a816604d2ce7b8dad0e5865de81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Ricks?= Date: Tue, 25 Sep 2018 15:33:30 +0200 Subject: [PATCH 09/12] Don't save settings into store when loading dashboard settings Remove the hack to put the defaults of the dashboards into the store when the dashboard is rendered for the first time. --- gsa/src/web/pages/start/page.js | 22 +++------------------- 1 file changed, 3 insertions(+), 19 deletions(-) diff --git a/gsa/src/web/pages/start/page.js b/gsa/src/web/pages/start/page.js index 144ef0ddbb..439c846551 100644 --- a/gsa/src/web/pages/start/page.js +++ b/gsa/src/web/pages/start/page.js @@ -220,25 +220,9 @@ class StartPage extends React.Component { }); } - handleLoadDashboardSettings(dashboardId, defaultSettings) { - const {byId, defaults = {}} = this.props; - - this.saveSettings({ - byId: { - ...byId, - [dashboardId]: { - ...defaultSettings, - ...byId[dashboardId], - }, - }, - defaults: { - ...defaults, - [dashboardId]: { - ...defaults[dashboardId], - ...defaultSettings, - }, - }, - }); + handleLoadDashboardSettings() { + // do nothing + // all defaults and settings are already provided } handleResetDashboard(dashboardId) { From c6be2f3b9eb9b046a522eaa9d70c5543bd615cb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Ricks?= Date: Tue, 25 Sep 2018 15:34:23 +0200 Subject: [PATCH 10/12] Allow to select default displays when creating a new dashboard When a new dashboard will be added to the main page allow to select a "template" of displays to show initially. --- gsa/src/web/pages/start/newdashboarddialog.js | 100 +++++++++++++++--- 1 file changed, 88 insertions(+), 12 deletions(-) diff --git a/gsa/src/web/pages/start/newdashboarddialog.js b/gsa/src/web/pages/start/newdashboarddialog.js index 3663805dc0..09611ab410 100644 --- a/gsa/src/web/pages/start/newdashboarddialog.js +++ b/gsa/src/web/pages/start/newdashboarddialog.js @@ -30,10 +30,22 @@ import SaveDialog from 'web/components/dialog/savedialog'; import FormGroup from 'web/components/form/formgroup'; import TextField from 'web/components/form/textfield'; +import Select from 'web/components/form/select'; /* eslint-disable max-len */ +import {CertBundCreatedDisplay} from 'web/pages/certbund/dashboard/createddisplay'; +import {CertBundCvssDisplay} from 'web/pages/certbund/dashboard/cvssdisplay'; import {CvesCreatedDisplay} from 'web/pages/cves/dashboard/createddisplay'; +import {CvesSeverityClassDisplay} from 'web/pages/cves/dashboard/severityclassdisplay'; +import {HostsModifiedDisplay} from 'web/pages/hosts/dashboard/modifieddisplay'; +import {HostsTopologyDisplay} from 'web/pages/hosts/dashboard/topologydisplay'; +import {HostsVulnScoreDisplay} from 'web/pages/hosts/dashboard/vulnscoredisplay'; import {NvtsSeverityClassDisplay} from 'web/pages/nvts/dashboard/severityclassdisplay'; +import {OsSeverityClassDisplay} from 'web/pages/operatingsystems/dashboard/severityclassdisplay'; +import {OsVulnScoreDisplay} from 'web/pages/operatingsystems/dashboard/vulnscoredisplay'; +import {ReportsHighResultsDisplay} from 'web/pages/reports/dashboard/highresultsdisplay'; +import {ReportsSeverityDisplay} from 'web/pages/reports/dashboard/severityclassdisplay'; +import {ResultsSeverityDisplay} from 'web/pages/results/dashboard/severityclassdisplay'; import {TasksSeverityDisplay} from 'web/pages/tasks/dashboard/severityclassdisplay'; import {TasksStatusDisplay} from 'web/pages/tasks/dashboard/statusdisplay'; /* eslint-enable max-len */ @@ -50,6 +62,41 @@ export const DEFAULT_DISPLAYS = [ ], ]; +const SCAN_DEFAULT_DISPLAYS = [ + [ + ResultsSeverityDisplay.displayId, + ReportsSeverityDisplay.displayId, + ], [ + TasksStatusDisplay.displayId, + ReportsHighResultsDisplay.displayId, + TasksSeverityDisplay.displayId, + ], +]; + +const ASSET_DEFAULT_DISPLAYS = [ + [ + HostsVulnScoreDisplay.displayId, + HostsTopologyDisplay.displayId, + OsVulnScoreDisplay.displayId, + ], [ + OsSeverityClassDisplay.displayId, + HostsModifiedDisplay.displayId, + ], +]; + +const SECINFO_DEFAULT_DISPLAYS = [ + [ + NvtsSeverityClassDisplay.displayId, + CvesCreatedDisplay.displayId, + CvesSeverityClassDisplay.displayId, + ], [ + CertBundCreatedDisplay.displayId, + CertBundCvssDisplay.displayId, + ], +]; + +const EMPTY_DISPLAYS = []; + const NewDashboardDialog = ({ onClose, onSave, @@ -62,6 +109,7 @@ const NewDashboardDialog = ({ minWidth={340} defaultValues={{ title: _('Unnamed'), + defaultDisplays: DEFAULT_DISPLAYS, }} onClose={onClose} onSave={onSave} @@ -70,18 +118,46 @@ const NewDashboardDialog = ({ values, onValueChange, }) => ( - - - + + + + + +