Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Report results loading #1863

Merged
merged 27 commits into from
Dec 17, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
464faeb
Pass filter as defaultFilter prop by default
bjoernricks Dec 13, 2019
5e12204
Adjust delta report details component for withDefaultFilter changes
bjoernricks Dec 13, 2019
fd8656a
Fix thresholdmessage
bjoernricks Dec 13, 2019
71195ab
Load report results with get_results
bjoernricks Dec 13, 2019
dc4a3ee
Use own component for delta results
bjoernricks Dec 16, 2019
17c229c
Allow for better debugging of the Reload component
bjoernricks Dec 16, 2019
3e59b95
Add reportId to reload messages of report details page
bjoernricks Dec 16, 2019
5f438eb
Add reload to ResultsTab
bjoernricks Dec 16, 2019
c9a1428
Drop obsolete componentDidMount method from ResultsTab
bjoernricks Dec 16, 2019
6cfba2a
Only display simplified filter at ResultsTab
bjoernricks Dec 16, 2019
02edbeb
Extend gsad to allow using _and_report_id filter param
bjoernricks Dec 16, 2019
9399faf
Use new internal filter keyword for getting results of a report
bjoernricks Dec 16, 2019
a3a97af
Fix loading results if ResultTab wasn't mounted before
bjoernricks Dec 16, 2019
545f960
Display full result filter at ResultsTab
bjoernricks Dec 16, 2019
8dbf9d4
Use the loaded report filter for ResultsTab too
bjoernricks Dec 16, 2019
a73af85
Display results loading errors at ResultsTab
bjoernricks Dec 17, 2019
0046754
Display report loading error at report summary
bjoernricks Dec 17, 2019
cd01d8c
Rename entityError to reportError
bjoernricks Dec 17, 2019
6c5e62f
Don't crash report summary if no filter is available
bjoernricks Dec 17, 2019
90846ba
Fix AlertActions properties
bjoernricks Dec 17, 2019
0751add
Use reportId directly where possible
bjoernricks Dec 17, 2019
423abc3
Rename loading prop of report ToolBarIcons
bjoernricks Dec 17, 2019
dfe0808
Fix passing the report to the ToolBarIcons
bjoernricks Dec 17, 2019
4bebd80
Fix displaying initial loading
bjoernricks Dec 17, 2019
817f451
Rename filter prop to reportFilter
bjoernricks Dec 17, 2019
3924153
Use an own reset filter for reports
bjoernricks Dec 17, 2019
70b473e
Add changelog entry
bjoernricks Dec 17, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
[#1507](https://github.com/greenbone/gsa/pull/1507)

### Changed
- Load report results with separate requests [#1863](https://github.com/greenbone/gsa/pull/1863)
- Only load full report if the report has less than 25000 results [#1851](https://github.com/greenbone/gsa/pull/1851)
- Only render report information, results and errors if a result has more than 25000 results [#1849](https://github.com/greenbone/gsa/pull/1849)
- Limit the length of result description with a div [#1834](https://github.com/greenbone/gsa/pull/1834)
Expand Down
32 changes: 20 additions & 12 deletions gsa/src/web/components/loading/reload.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,9 @@ class Reload extends React.Component {

componentDidMount() {
this.isRunning = true;
const {reload, load: loadFunc = reload} = this.props;
const {reload, load: loadFunc = reload, name} = this.props;

log.debug('Initial loading.');
log.debug('Initial loading for', name);

this.activateVisibilityListener();
this.internalLoad(loadFunc); // initial loading
Expand Down Expand Up @@ -116,19 +116,19 @@ class Reload extends React.Component {
}

startTimer() {
const {name} = this.props;

if (!this.isRunning || this.hasTimer()) {
log.debug('Not starting timer. A timer is already running.', {
log.debug('Not starting timer for', name, 'A timer is already running.', {
isRunning: this.isRunning,
timer: this.timer,
});
return;
}

const {name} = this.props;

const loadTime = this.endMeasurement();

log.debug('Loading time was', loadTime, 'milliseconds');
log.debug('Loading time for', name, 'was', loadTime, 'milliseconds');

let interval = this.getReloadInterval();

Expand All @@ -148,7 +148,7 @@ class Reload extends React.Component {
name,
);
} else {
log.debug('Not starting timer. Interval was', interval);
log.debug('Not starting timer for', name, 'Interval was', interval);
}
}

Expand All @@ -172,7 +172,13 @@ class Reload extends React.Component {
}

handleTimer() {
log.debug('Timer', this.timer, 'finished. Reloading data.');
log.debug(
'Timer',
this.timer,
'for',
this.props.name,
'finished. Reloading data.',
);

this.resetTimer();

Expand Down Expand Up @@ -208,7 +214,7 @@ class Reload extends React.Component {
return Promise.resolve();
}

log.debug('Reloading requested.', options);
log.debug('Reloading for', this.props.name, 'requested.', options);
return this.internalLoad(this.props.reload, options);
}

Expand All @@ -219,19 +225,21 @@ class Reload extends React.Component {
return Promise.resolve();
}

log.debug('Loading requested.', options);
log.debug('Loading for', this.props.name, 'requested.', options);

this.startMeasurement();

return loadFunc(options)
.then(() => {
log.debug('Loading finished.');
log.debug('Loading for', this.props.name, 'finished.');
this.startTimer();
})
.catch(error => {
/* don't restart timer to avoid raising several errors */
log.debug(
'Loading Promise has been rejected. Not starting new timer.',
'Loading Promise for',
this.props.name,
'has been rejected. Not starting new timer.',
error,
);
});
Expand Down
7 changes: 5 additions & 2 deletions gsa/src/web/entities/withDefaultFilter.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,13 @@ import React from 'react';

import DefaultFilter from './defaultfilter';

const withDefaultFilter = entityType => Component => {
const withDefaultFilter = (entityType, name = 'defaultFilter') => Component => {
const DefaultFilterWrapper = props => (
<DefaultFilter entityType={entityType}>
{({filter}) => <Component filter={filter} {...props} />}
{({filter}) => {
const filterProps = {[name]: filter, ...props};
return <Component {...filterProps} />;
}}
</DefaultFilter>
);
return DefaultFilterWrapper;
Expand Down
6 changes: 3 additions & 3 deletions gsa/src/web/pages/reports/deltadetailscontent.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ import EntityTags from 'web/entity/tags';

import PropTypes from 'web/utils/proptypes';

import ResultsTab from './details/resultstab';
import DeltaResultsTab from './details/deltaresultstab';
import Summary from './details/summary';
import TabTitle from './details/tabtitle';
import ToolBarIcons from './details/toolbaricons';
Expand Down Expand Up @@ -146,7 +146,7 @@ const PageContent = ({
<ToolBarIcons
delta={true}
filter={filter}
loading={isLoading}
isLoading={isLoading}
report={report}
showError={showError}
showSuccessMessage={showSuccessMessage}
Expand Down Expand Up @@ -204,7 +204,7 @@ const PageContent = ({
/>
</TabPanel>
<TabPanel>
<ResultsTab
<DeltaResultsTab
counts={isDefined(results.counts) ? results.counts : {}}
delta={true}
filter={filter}
Expand Down
10 changes: 5 additions & 5 deletions gsa/src/web/pages/reports/deltadetailspage.js
Original file line number Diff line number Diff line change
Expand Up @@ -696,17 +696,17 @@ const load = ({
);
};

const DeltaReportDetailsWrapper = ({filter, reportFilter, ...props}) => (
const DeltaReportDetailsWrapper = ({defaultFilter, reportFilter, ...props}) => (
<Reload
name="report"
load={load({...props, defaultFilter: filter})}
reload={load({...props, defaultFilter: filter, reportFilter})}
load={load({...props, defaultFilter})}
reload={load({...props, defaultFilter, reportFilter})}
reloadInterval={() => reloadInterval(props.entity)}
>
{({reload}) => (
<DeltaReportDetails
{...props}
defaultFilter={filter}
defaultFilter={defaultFilter}
reportFilter={reportFilter}
reload={reload}
/>
Expand All @@ -715,8 +715,8 @@ const DeltaReportDetailsWrapper = ({filter, reportFilter, ...props}) => (
);

DeltaReportDetailsWrapper.propTypes = {
defaultFilter: PropTypes.filter,
entity: PropTypes.model,
filter: PropTypes.filter,
gmp: PropTypes.gmp.isRequired,
reportFilter: PropTypes.filter,
};
Expand Down
6 changes: 3 additions & 3 deletions gsa/src/web/pages/reports/details/alertactions.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ class AlertActions extends React.Component {
const {
filter,
gmp,
report,
reportId,
reportComposerDefaults,
showErrorMessage,
showSuccessMessage,
Expand All @@ -119,7 +119,7 @@ class AlertActions extends React.Component {

return gmp.report
.alert({
report_id: report.id,
report_id: reportId,
alert_id: alertId,
filter: newFilter.simple(),
})
Expand Down Expand Up @@ -219,8 +219,8 @@ AlertActions.propTypes = {
gmp: PropTypes.gmp.isRequired,
loadAlerts: PropTypes.func.isRequired,
loadReportComposerDefaults: PropTypes.func.isRequired,
report: PropTypes.model.isRequired,
reportComposerDefaults: PropTypes.object,
reportId: PropTypes.id.isRequired,
saveReportComposerDefaults: PropTypes.func.isRequired,
showError: PropTypes.func.isRequired,
showErrorMessage: PropTypes.func.isRequired,
Expand Down
159 changes: 159 additions & 0 deletions gsa/src/web/pages/reports/details/deltaresultstab.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
/* Copyright (C) 2017-2019 Greenbone Networks GmbH
*
* SPDX-License-Identifier: GPL-2.0-or-later
*
* 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 PropTypes from 'web/utils/proptypes';

import ResultsTable from 'web/pages/results/table';

import {
makeCompareDate,
makeCompareIp,
makeCompareNumber,
makeCompareSeverity,
makeCompareString,
} from 'web/utils/sort';

import EmptyReport from './emptyreport';
import EmptyResultsReport from './emptyresultsreport';
import ReportEntitiesContainer from './reportentitiescontainer';

const resultsSortFunctions = {
delta: makeCompareString(entity => entity.delta.delta_type),
created: makeCompareDate('creationTime'),
host: makeCompareIp(entity => entity.host.name),
hostname: makeCompareString(entity => entity.host.hostname),
location: makeCompareString('port'),
qod: makeCompareNumber(entity => entity.qod.value),
severity: makeCompareSeverity(),
solution_type: makeCompareString(entity => entity.nvt.tags.solution_type),
vulnerability: makeCompareString('vulnerability'),
};

const ResultsTab = ({
counts,
delta = false,
filter,
hasTarget,
isUpdating = false,
progress,
results,
sortField,
sortReverse,
status,
onFilterAddLogLevelClick,
onFilterDecreaseMinQoDClick,
onFilterEditClick,
onFilterRemoveSeverityClick,
onFilterRemoveClick,
onInteraction,
onSortChange,
onTargetEditClick,
}) => {
if (counts.filtered === 0) {
if (counts.all === 0) {
return (
<EmptyReport
hasTarget={hasTarget}
status={status}
progress={progress}
onTargetEditClick={onTargetEditClick}
/>
);
} else if (counts.all > 0) {
return (
<EmptyResultsReport
all={counts.all}
filter={filter}
onFilterAddLogLevelClick={onFilterAddLogLevelClick}
onFilterDecreaseMinQoDClick={onFilterDecreaseMinQoDClick}
onFilterEditClick={onFilterEditClick}
onFilterRemoveClick={onFilterRemoveClick}
onFilterRemoveSeverityClick={onFilterRemoveSeverityClick}
/>
);
}
}
return (
<ReportEntitiesContainer
entities={results}
counts={counts}
filter={filter}
sortField={sortField}
sortFunctions={resultsSortFunctions}
sortReverse={sortReverse}
onInteraction={onInteraction}
>
{({
entities,
entitiesCounts,
sortBy,
sortDir,
onFirstClick,
onLastClick,
onNextClick,
onPreviousClick,
}) => (
<ResultsTable
delta={delta}
entities={entities}
entitiesCounts={entitiesCounts}
filter={filter}
footer={false}
isUpdating={isUpdating}
links={!delta}
sortBy={sortBy}
sortDir={sortDir}
toggleDetailsIcon={false}
onSortChange={onSortChange}
onFirstClick={onFirstClick}
onLastClick={onLastClick}
onNextClick={onNextClick}
onPreviousClick={onPreviousClick}
/>
)}
</ReportEntitiesContainer>
);
};

ResultsTab.propTypes = {
counts: PropTypes.oneOfType([PropTypes.counts, PropTypes.object]).isRequired,
delta: PropTypes.bool,
filter: PropTypes.filter.isRequired,
hasTarget: PropTypes.bool,
isUpdating: PropTypes.bool,
progress: PropTypes.number.isRequired,
results: PropTypes.array,
sortField: PropTypes.string.isRequired,
sortReverse: PropTypes.bool.isRequired,
status: PropTypes.string.isRequired,
onFilterAddLogLevelClick: PropTypes.func.isRequired,
onFilterDecreaseMinQoDClick: PropTypes.func.isRequired,
onFilterEditClick: PropTypes.func.isRequired,
onFilterRemoveClick: PropTypes.func.isRequired,
onFilterRemoveSeverityClick: PropTypes.func.isRequired,
onInteraction: PropTypes.func.isRequired,
onSortChange: PropTypes.func.isRequired,
onTargetEditClick: PropTypes.func.isRequired,
};

export default ResultsTab;

// vim: set ts=2 sw=2 tw=80:
Loading