diff --git a/public/locales/gsa-de.json b/public/locales/gsa-de.json
index b0215e660d..ab1701b290 100644
--- a/public/locales/gsa-de.json
+++ b/public/locales/gsa-de.json
@@ -824,7 +824,7 @@
"Include log messages in your filter settings.": "Log-Nachrichten in die Filtereinstellungen einbeziehen.",
"Include report": "Bericht einfügen",
"Included": "Beinhaltet",
- "Incomplete": "Inkomplett",
+ "Incomplete": "Unvollständig",
"Info": "Info",
"Information": "Informationen",
"Inheriting user": "Erbender Benutzer",
diff --git a/src/gmp/commands/__tests__/auditreport.js b/src/gmp/commands/__tests__/auditreport.js
index e6a78a2765..ce7091ee06 100644
--- a/src/gmp/commands/__tests__/auditreport.js
+++ b/src/gmp/commands/__tests__/auditreport.js
@@ -15,11 +15,11 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
*/
-import {createHttp, createEntityResponse} from '../testing';
-import {AuditReportCommand} from '../auditreports';
+import {createHttp, createEntityResponse} from 'gmp/commands/testing';
+import {AuditReportCommand} from 'gmp/commands/auditreports';
-describe('ReportCommand tests', () => {
- test('should request single report', () => {
+describe('AuditReportCommand tests', () => {
+ test('should request single audit report', () => {
const response = createEntityResponse('report', {_id: 'foo'});
const fakeHttp = createHttp(response);
diff --git a/src/gmp/commands/__tests__/auditreports.js b/src/gmp/commands/__tests__/auditreports.js
index 7e6920e0b7..d6fdb42885 100644
--- a/src/gmp/commands/__tests__/auditreports.js
+++ b/src/gmp/commands/__tests__/auditreports.js
@@ -22,7 +22,7 @@ import {
createEntitiesResponse,
createAggregatesResponse,
} from '../testing';
-import {AuditReportsCommand} from '../auditreports';
+import {AuditReportsCommand} from 'gmp/commands/auditreports';
describe('AuditReportsCommand tests', () => {
test('should return all audit reports', () => {
diff --git a/src/gmp/models/auditreport.js b/src/gmp/models/auditreport.js
index f666f75496..40f1bd0c9d 100644
--- a/src/gmp/models/auditreport.js
+++ b/src/gmp/models/auditreport.js
@@ -57,11 +57,11 @@ class AuditReport extends Model {
copy.report = AuditReportReport.fromElement(report);
}
- copy.report_format = parseModelFromElement(report_format, 'reportformat');
+ copy.reportFormat = parseModelFromElement(report_format, 'reportformat');
copy.task = parseModelFromElement(task, 'task');
- copy.report_type = type;
- copy.content_type = content_type;
+ copy.reportType = type;
+ copy.contentType = content_type; // revert ?
copy.scan_start = parseDate(scan_start);
copy.timestamp = parseDate(timestamp);
diff --git a/src/gmp/models/report/auditreport.js b/src/gmp/models/report/auditreport.js
index 8c1c559280..cc5f503c7b 100644
--- a/src/gmp/models/report/auditreport.js
+++ b/src/gmp/models/report/auditreport.js
@@ -15,14 +15,14 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
*/
-import {isDefined} from '../../utils/identity';
-import {isEmpty} from '../../utils/string';
+import {isDefined} from 'gmp/utils/identity';
+import {isEmpty} from 'gmp/utils/string';
-import {parseDate} from '../../parser';
+import {parseDate} from 'gmp/parser';
-import {parseFilter} from '../../collection/parser';
+import {parseFilter} from 'gmp/collection/parser';
-import Model from '../../model';
+import Model from 'gmp/model';
import ReportTask from './task';
@@ -44,14 +44,24 @@ class AuditReportReport extends Model {
static parseElement(element) {
const copy = super.parseElement(element);
- const {delta, compliance, scan_start, scan_end, task, scan, timestamp} =
- element;
+ const {
+ delta,
+ compliance,
+ compliance_count,
+ scan_start,
+ scan_end,
+ task,
+ scan,
+ timestamp,
+ } = element;
const filter = parseFilter(element);
copy.filter = filter;
- copy.report_type = element._type;
+ copy.reportType = element._type;
+
+ // copy.scanRunStatus = element.scan_run_status;
delete copy.filters;
@@ -62,6 +72,31 @@ class AuditReportReport extends Model {
};
}
+ if (isDefined(compliance_count)) {
+ copy.complianceCounts = {
+ filtered: parseInt(compliance_count.filtered),
+ full: parseInt(compliance_count.full),
+ incomplete: {
+ filtered: parseInt(compliance_count.incomplete.filtered),
+ full: parseInt(compliance_count.incomplete.full),
+ },
+ no: {
+ filtered: parseInt(compliance_count.no.filtered),
+ full: parseInt(compliance_count.no.full),
+ },
+ undefined: {
+ filtered: parseInt(compliance_count.undefined.filtered),
+ full: parseInt(compliance_count.undefined.full),
+ },
+ yes: {
+ filtered: parseInt(compliance_count.yes.filtered),
+ full: parseInt(compliance_count.yes.full),
+ },
+ };
+ }
+
+ delete copy.compliance_count;
+
copy.task = ReportTask.fromElement(task);
copy.results = parseResults(element, filter);
@@ -72,7 +107,7 @@ class AuditReportReport extends Model {
delete copy.host;
- copy.operatingsystems = parseOperatingSystems(element, filter);
+ copy.operatingSystems = parseOperatingSystems(element, filter);
copy.errors = parse_errors(element, filter);
@@ -112,7 +147,7 @@ class AuditReportReport extends Model {
}
isDeltaReport() {
- return this.report_type === 'delta';
+ return this.reportType === 'delta';
}
}
diff --git a/src/gmp/models/report/host.js b/src/gmp/models/report/host.js
index 4563e0a7c8..9034d8effa 100644
--- a/src/gmp/models/report/host.js
+++ b/src/gmp/models/report/host.js
@@ -50,7 +50,7 @@ class Host {
warning: 0,
total: 0,
};
- this.compliance_counts = {
+ this.complianceCounts = {
yes: 0,
no: 0,
incomplete: 0,
@@ -77,10 +77,12 @@ class Host {
host_compliance,
} = element;
- copy.host_compliance = isDefined(host_compliance)
+ copy.hostCompliance = isDefined(host_compliance)
? host_compliance
: 'undefined';
+ delete copy.host_compliance;
+
if (isEmpty(asset._asset_id)) {
delete copy.asset;
} else {
@@ -111,7 +113,7 @@ class Host {
}
if (isDefined(compliance_count)) {
- copy.compliance_counts = {
+ copy.complianceCounts = {
yes: parse_page_count(compliance_count.yes),
no: parse_page_count(compliance_count.no),
incomplete: parse_page_count(compliance_count.incomplete),
@@ -119,7 +121,7 @@ class Host {
total: parse_page_count(compliance_count),
};
} else {
- copy.compliance_counts = {
+ copy.complianceCounts = {
yes: 0,
no: 0,
incomplete: 0,
diff --git a/src/web/components/bar/compliancebar.js b/src/web/components/bar/compliancebar.js
index 2c08f44707..e4d35fc30d 100644
--- a/src/web/components/bar/compliancebar.js
+++ b/src/web/components/bar/compliancebar.js
@@ -19,10 +19,10 @@ import React from 'react';
import {isDefined} from 'gmp/utils/identity';
-import PropTypes from '../../utils/proptypes.js';
-import Theme from 'web/utils/theme.js';
+import PropTypes from 'web/utils/proptypes';
+import Theme from 'web/utils/theme';
-import ProgressBar from './progressbar.js';
+import ProgressBar from './progressbar';
import {getTranslatableReportCompliance} from 'gmp/models/auditreport';
const ComplianceBar = ({compliance, toolTip}) => {
@@ -30,13 +30,13 @@ const ComplianceBar = ({compliance, toolTip}) => {
let background;
if (compliance === 'no') {
- background = Theme.compliance_no;
+ background = Theme.complianceNo;
} else if (compliance === 'incomplete') {
- background = Theme.compliance_incomplete;
+ background = Theme.complianceIncomplete;
} else if (compliance === 'yes') {
- background = Theme.compliance_yes;
+ background = Theme.complianceYes;
} else {
- background = Theme.compliance_undefined;
+ background = Theme.complianceUndefined;
}
const toolTipText = isDefined(toolTip) ? toolTip : title;
diff --git a/src/web/components/label/compliancestate.js b/src/web/components/label/compliancestate.js
index 9e9ba5badf..ca6cb43c78 100644
--- a/src/web/components/label/compliancestate.js
+++ b/src/web/components/label/compliancestate.js
@@ -15,13 +15,11 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
*/
-import React from 'react';
-
import styled from 'styled-components';
import _ from 'gmp/locale';
import {styledExcludeProps} from 'web/utils/styledConfig';
-import Theme from 'web/utils/theme.js';
+import Theme from 'web/utils/theme';
const Label = styledExcludeProps(styled.div, [
'backgroundColor',
@@ -40,53 +38,45 @@ const Label = styledExcludeProps(styled.div, [
border-color: ${props => props.borderColor};
`;
-const YesLabel = props => {
- return (
-
- );
-};
+const YesLabel = props => (
+
+);
-const NoLabel = props => {
- return (
-
- );
-};
+const NoLabel = props => (
+
+);
-const IncompleteLabel = props => {
- return (
-
- );
-};
+const IncompleteLabel = props => (
+
+);
-const UndefinedLabel = props => {
- return (
-
- );
-};
+const UndefinedLabel = props => (
+
+);
export const ComplianceStateLabels = {
Yes: YesLabel,
diff --git a/src/web/components/powerfilter/__tests__/compliancelevelsgroup.js b/src/web/components/powerfilter/__tests__/compliancelevelsgroup.js
index 0f873cc3bf..d1ac6990fe 100644
--- a/src/web/components/powerfilter/__tests__/compliancelevelsgroup.js
+++ b/src/web/components/powerfilter/__tests__/compliancelevelsgroup.js
@@ -15,11 +15,9 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
*/
-import React from 'react';
-
import {render, fireEvent} from 'web/utils/testing';
-import ComplianceLevelsFilterGroup from '../compliancelevelsgroup';
+import ComplianceLevelsFilterGroup from 'web/components/powerfilter/compliancelevelsgroup';
import Filter from 'gmp/models/filter';
diff --git a/src/web/components/powerfilter/compliancelevelsgroup.js b/src/web/components/powerfilter/compliancelevelsgroup.js
index 2d16d5ae2c..3000f17c14 100644
--- a/src/web/components/powerfilter/compliancelevelsgroup.js
+++ b/src/web/components/powerfilter/compliancelevelsgroup.js
@@ -22,24 +22,18 @@ import _ from 'gmp/locale';
import {isDefined} from 'gmp/utils/identity';
-import PropTypes from '../../utils/proptypes.js';
+import PropTypes from 'web/utils/proptypes';
-import Checkbox from '../form/checkbox.js';
-import FormGroup from '../form/formgroup.js';
+import Checkbox from 'web/components/form/checkbox';
+import FormGroup from 'web/components/form/formgroup';
-import IconDivider from '../layout/icondivider.js';
+import IconDivider from 'web/components/layout/icondivider';
-import ComplianceStateLabels from '../label/compliancestate.js';
+import ComplianceStateLabels from 'web/components/label/compliancestate';
-class ComplianceLevelsFilterGroup extends React.Component {
- constructor(...args) {
- super(...args);
-
- this.handleComplianceChange = this.handleComplianceChange.bind(this);
- }
-
- handleComplianceChange(value, level) {
- const {filter, onChange, onRemove, isResult = false} = this.props;
+const ComplianceLevelsFilterGroup = props => {
+ const handleComplianceChange = (value, level) => {
+ const {filter, onChange, onRemove, isResult = false} = props;
const filter_name = isResult
? 'compliance_levels'
@@ -63,54 +57,52 @@ class ComplianceLevelsFilterGroup extends React.Component {
onChange(compliance, filter_name);
}
}
- }
+ };
- render() {
- const {filter, isResult} = this.props;
+ const {filter, isResult} = props;
- let compliance_levels = filter.get(
- isResult ? 'compliance_levels' : 'report_compliance_levels',
- );
+ let compliance_levels = filter.get(
+ isResult ? 'compliance_levels' : 'report_compliance_levels',
+ );
- if (!isDefined(compliance_levels)) {
- compliance_levels = '';
- }
- return (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- );
+ if (!isDefined(compliance_levels)) {
+ compliance_levels = '';
}
-}
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
ComplianceLevelsFilterGroup.propTypes = {
filter: PropTypes.filter.isRequired,
diff --git a/src/web/pages/reports/__mocks__/mockauditdeltareport.js b/src/web/pages/reports/__mocks__/mockauditdeltareport.js
index 5f5de621c2..b6e04c4860 100644
--- a/src/web/pages/reports/__mocks__/mockauditdeltareport.js
+++ b/src/web/pages/reports/__mocks__/mockauditdeltareport.js
@@ -350,7 +350,26 @@ export const getMockAuditDeltaReport = () => {
os: {count: 2},
ssl_certs: {count: 2},
compliance: {filtered: 'no', full: 'no'},
- compliance_count: {__text: 3, full: 3, filtered: 2},
+ compliance_count: {
+ full: 3,
+ filtered: 2,
+ incomplete: {
+ full: 5,
+ filtered: 1,
+ },
+ yes: {
+ full: 2,
+ filtered: 3,
+ },
+ no: {
+ full: 1,
+ filtered: 2,
+ },
+ undefined: {
+ full: 2,
+ filtered: 0,
+ },
+ },
results: {result: [result1, result2, result3]},
hosts: {count: 3},
host: [host1, host2, host3],
diff --git a/src/web/pages/reports/__mocks__/mockauditreport.js b/src/web/pages/reports/__mocks__/mockauditreport.js
index 8126f50271..409e52e283 100644
--- a/src/web/pages/reports/__mocks__/mockauditreport.js
+++ b/src/web/pages/reports/__mocks__/mockauditreport.js
@@ -378,7 +378,7 @@ export const getMockAuditReport = () => {
report: entity.report,
results: entity.report.results,
hosts: entity.report.hosts,
- operatingsystems: entity.report.operatingsystems,
+ operatingsystems: entity.report.operatingSystems,
tlsCertificates: entity.report.tlsCertificates,
errors: entity.report.errors,
task: entity.report.task,
diff --git a/src/web/pages/reports/__tests__/auditdeltadetailspage.js b/src/web/pages/reports/__tests__/auditdeltadetailspage.js
index 2bb53f403c..294ff3e2c6 100644
--- a/src/web/pages/reports/__tests__/auditdeltadetailspage.js
+++ b/src/web/pages/reports/__tests__/auditdeltadetailspage.js
@@ -28,7 +28,7 @@ import {rendererWith} from 'web/utils/testing';
import {getMockAuditDeltaReport} from 'web/pages/reports/__mocks__/mockauditdeltareport';
-import DeltaDetailsContent from '../deltadetailscontent';
+import DeltaDetailsContent from 'web/pages/reports/deltadetailscontent';
setLocale('en');
diff --git a/src/web/pages/reports/__tests__/auditdetailscontent.js b/src/web/pages/reports/__tests__/auditdetailscontent.js
index 43c5250f9f..dc22c73dcd 100644
--- a/src/web/pages/reports/__tests__/auditdetailscontent.js
+++ b/src/web/pages/reports/__tests__/auditdetailscontent.js
@@ -28,7 +28,7 @@ import {rendererWith} from 'web/utils/testing';
import {getMockAuditReport} from 'web/pages/reports/__mocks__/mockauditreport';
-import DetailsContent from '../auditdetailscontent';
+import DetailsContent from 'web/pages/reports/auditdetailscontent';
setLocale('en');
diff --git a/src/web/pages/reports/__tests__/auditfilterdialog.js b/src/web/pages/reports/__tests__/auditfilterdialog.js
index a6da627062..f1de966899 100644
--- a/src/web/pages/reports/__tests__/auditfilterdialog.js
+++ b/src/web/pages/reports/__tests__/auditfilterdialog.js
@@ -24,7 +24,7 @@ import Filter from 'gmp/models/filter';
import {rendererWith} from 'web/utils/testing';
-import AuditReportFilter from '../auditfilterdialog';
+import AuditReportFilter from 'web/pages/reports/auditfilterdialog';
setLocale('en');
diff --git a/src/web/pages/reports/__tests__/detailsfilterdialog.js b/src/web/pages/reports/__tests__/detailsfilterdialog.js
index 65f7382ba9..35ea2209b8 100644
--- a/src/web/pages/reports/__tests__/detailsfilterdialog.js
+++ b/src/web/pages/reports/__tests__/detailsfilterdialog.js
@@ -24,7 +24,7 @@ import Filter from 'gmp/models/filter';
import {rendererWith} from 'web/utils/testing';
-import FilterDialog from '../detailsfilterdialog';
+import FilterDialog from 'web/pages/reports/detailsfilterdialog';
setLocale('en');
diff --git a/src/web/pages/reports/auditdashboard/index.js b/src/web/pages/reports/auditdashboard/index.js
index 3118683ac4..c88606ec8c 100644
--- a/src/web/pages/reports/auditdashboard/index.js
+++ b/src/web/pages/reports/auditdashboard/index.js
@@ -16,9 +16,7 @@
* along with this program. If not, see .
*/
-import React from 'react';
-
-import Dashboard from '../../../components/dashboard/dashboard';
+import Dashboard from 'web/components/dashboard/dashboard';
import {
ReportComplianceDisplay,
diff --git a/src/web/pages/reports/auditdashboard/loaders.js b/src/web/pages/reports/auditdashboard/loaders.js
index d8ed201bb3..792148413f 100644
--- a/src/web/pages/reports/auditdashboard/loaders.js
+++ b/src/web/pages/reports/auditdashboard/loaders.js
@@ -15,8 +15,6 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
*/
-import React from 'react';
-
import Loader, {
loadFunc,
loaderPropTypes,
diff --git a/src/web/pages/reports/auditdeltadetailspage.js b/src/web/pages/reports/auditdeltadetailspage.js
index c406a98796..cefaabd255 100644
--- a/src/web/pages/reports/auditdeltadetailspage.js
+++ b/src/web/pages/reports/auditdeltadetailspage.js
@@ -16,9 +16,11 @@
* along with this program. If not, see .
*/
-import React from 'react';
+import React, {useEffect, useState} from 'react';
-import {connect} from 'react-redux';
+import {useDispatch, useSelector, shallowEqual} from 'react-redux';
+
+import {useRouteMatch} from 'react-router-dom';
import _ from 'gmp/locale';
@@ -63,7 +65,6 @@ import {
import {loadUserSettingDefaults} from 'web/store/usersettings/defaults/actions';
import {getUserSettingsDefaults} from 'web/store/usersettings/defaults/selectors';
-import {loadUserSettingsDefaultFilter} from 'web/store/usersettings/defaultfilters/actions';
import {getUserSettingsDefaultFilter} from 'web/store/usersettings/defaultfilters/selectors';
import {
@@ -71,11 +72,10 @@ import {
getUsername,
} from 'web/store/usersettings/selectors';
-import {create_pem_certificate} from 'web/utils/cert';
import compose from 'web/utils/compose';
import {generateFilename} from 'web/utils/render';
import PropTypes from 'web/utils/proptypes';
-import withGmp from 'web/utils/withGmp';
+import useGmp from 'web/utils/useGmp';
import TargetComponent from '../targets/component';
@@ -101,140 +101,161 @@ const getFilter = (entity = {}) => {
return report.filter;
};
-class DeltaAuditReportDetails extends React.Component {
- constructor(...args) {
- super(...args);
-
- this.state = {
- activeTab: 0,
- showFilterDialog: false,
- showDownloadReportDialog: false,
- sorting: {
- results: {
- sortField: 'compliant',
- sortReverse: true,
- },
- errors: {
- sortField: 'error',
- sortReverse: false,
- },
- },
- };
-
- this.handleActivateTab = this.handleActivateTab.bind(this);
- this.handleAddToAssets = this.handleAddToAssets.bind(this);
- this.handleChanged = this.handleChanged.bind(this);
- this.handleError = this.handleError.bind(this);
- this.handleFilterAddLogLevel = this.handleFilterAddLogLevel.bind(this);
- this.handleFilterChange = this.handleFilterChange.bind(this);
- this.handleFilterDecreaseMinQoD =
- this.handleFilterDecreaseMinQoD.bind(this);
- this.handleFilterCreated = this.handleFilterCreated.bind(this);
- this.handleFilterEditClick = this.handleFilterEditClick.bind(this);
- this.handleFilterRemoveSeverity =
- this.handleFilterRemoveSeverity.bind(this);
- this.handleFilterRemoveClick = this.handleFilterRemoveClick.bind(this);
- this.handleFilterResetClick = this.handleFilterResetClick.bind(this);
- this.handleRemoveFromAssets = this.handleRemoveFromAssets.bind(this);
- this.handleReportDownload = this.handleReportDownload.bind(this);
- this.handleTlsCertificateDownload =
- this.handleTlsCertificateDownload.bind(this);
- this.handleFilterDialogClose = this.handleFilterDialogClose.bind(this);
- this.handleSortChange = this.handleSortChange.bind(this);
-
- this.loadTarget = this.loadTarget.bind(this);
- this.handleOpenDownloadReportDialog =
- this.handleOpenDownloadReportDialog.bind(this);
- this.handleCloseDownloadReportDialog =
- this.handleCloseDownloadReportDialog.bind(this);
- }
-
- componentDidMount() {
- this.props.loadSettings();
- this.props.loadFilters();
- this.props.loadReportFormats();
- this.props.loadReportComposerDefaults();
- }
-
- componentDidUpdate(prevProps) {
- const {reportFormats} = this.props;
+const DeltaAuditReportDetails = props => {
+ const [activeTab, setActiveTab] = useState(0);
+ const [showFilterDialog, setShowFilterDialog] = useState(false);
+ const [showDownloadReportDialog, setShowDownloadReportDialog] =
+ useState(false);
+ const [reportFormatId, setReportFormatId] = useState(undefined);
+ const [isUpdating, setIsUpdating] = useState(false);
+ // storeAsDefault is set in SaveDialogContent
+ // eslint-disable-next-line no-unused-vars
+ const [storeAsDefault, setStoreAsDefault] = useState(undefined);
+
+ const [sorting, setSorting] = useState({
+ results: {
+ sortField: 'compliant',
+ sortReverse: true,
+ },
+ errors: {
+ sortField: 'error',
+ sortReverse: false,
+ },
+ });
+
+ const gmp = useGmp();
+ const dispatch = useDispatch();
+ const match = useRouteMatch();
+ const {id: reportId, deltaid: deltaReportId} = match.params;
+
+ const reportFormatsSel = useSelector(reportFormatsSelector);
+ const reportFormats = reportFormatsSel?.getAllEntities(REPORT_FORMATS_FILTER);
+ const userDefaultFilterSel = useSelector(
+ rootState => getUserSettingsDefaultFilter(rootState, 'result'),
+ shallowEqual,
+ );
+ const resultDefaultFilter = userDefaultFilterSel?.getFilter('result');
+ const reportComposerDefaults = useSelector(getReportComposerDefaults);
+ const userDefaultsSelector = useSelector(
+ getUserSettingsDefaults,
+ shallowEqual,
+ );
+ const reportExportFileName = userDefaultsSelector?.getValueByName(
+ 'reportexportfilename',
+ );
+ const username = useSelector(getUsername);
+ const filterSel = useSelector(filterSelector);
+ const filters = filterSel?.getAllEntities(RESULTS_FILTER_FILTER);
+ const [entity, entityError] = useSelector(state => {
+ const deltaSel = deltaAuditReportSelector(state);
+ return [
+ deltaSel?.getEntity(reportId, deltaReportId),
+ deltaSel?.getError(reportId, deltaReportId),
+ ];
+ });
+ const isLoading = !isDefined(entity);
+
+ useEffect(() => {
+ dispatch(loadUserSettingDefaults(gmp)());
+ dispatch(loadFilters(gmp)(RESULTS_FILTER_FILTER));
+ dispatch(loadReportFormats(gmp)(REPORT_FORMATS_FILTER));
+ dispatch(loadReportComposerDefaults(gmp)());
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, []);
+
+ useEffect(() => {
if (
- !isDefined(this.state.reportFormatId) &&
+ !isDefined(reportFormatId) &&
isDefined(reportFormats) &&
reportFormats.length > 0
) {
// set initial report format id if available
- const reportFormatId = first(reportFormats).id;
- if (isDefined(reportFormatId)) {
+ const initialReportFormatId = first(reportFormats).id;
+ if (isDefined(initialReportFormatId)) {
// ensure the report format id is only set if we really have one
// if no report format id is available we would create an infinite
// render loop here
- this.setState({reportFormatId});
+ setReportFormatId({initialReportFormatId});
+ } else {
+ // if there is no report format at all, throw a proper error message
+ // instead of just showing x is undefined JS stacktrace
+ const noReportFormatError = _(
+ 'The report cannot be displayed because' +
+ ' no Greenbone Vulnerability Manager report format is available.' +
+ ' This could be due to a missing gvmd data feed. Please update' +
+ ' the gvmd data feed, check the "feed import owner" setting, or' +
+ ' contact your system administrator.',
+ );
+ throw new Error(noReportFormatError);
}
}
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [reportFormats, reportFormatId]);
- if (
- prevProps.reportId !== this.props.reportId ||
- prevProps.deltaReportId !== this.props.deltaReportId
- ) {
- this.load();
- }
- }
+ useEffect(() => {
+ load();
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [reportId, deltaReportId]);
- load(filter) {
- log.debug('Loading deleta report', {
+ const load = filter => {
+ log.debug('Loading report', {
filter,
});
+ const {reportFilter: prevFilter} = props;
- this.setState(({lastFilter}) => ({
- isUpdating: isDefined(lastFilter) && !lastFilter.equals(filter), // show update indicator if filter has changed
- lastFilter: filter,
- }));
+ setIsUpdating(!isDefined(prevFilter) || !prevFilter.equals(filter));
- this.props.reload(filter).then(() => {
- this.setState({isUpdating: false});
- });
- }
+ props
+ .reload(filter)
+ .then(() => {
+ setIsUpdating(false);
+ })
+ .catch(() => {
+ setIsUpdating(false);
+ });
+ };
- reload() {
+ const reload = () => {
// reload data from backend
- this.load(this.state.lastFilter);
- }
+ load(props.reportFilter);
+ };
- handleChanged() {
- this.reload();
- }
+ const handleChanged = () => {
+ reload();
+ };
- handleError(error) {
- const {showError} = this.props;
+ const handleError = error => {
+ const {showError} = props;
log.error(error);
showError(error);
- }
-
- handleFilterChange(filter) {
- this.handleInteraction();
-
- this.load(filter);
- }
+ };
- handleFilterRemoveClick() {
- this.handleFilterChange(RESET_FILTER);
- }
+ const handleFilterChange = filter => {
+ handleInteraction();
+ load(filter);
+ };
- handleFilterResetClick() {
- this.handleFilterChange(this.props.resultDefaultFilter);
- }
+ const handleFilterRemoveClick = () => {
+ handleFilterChange(RESET_FILTER);
+ };
- handleActivateTab(index) {
- this.handleInteraction();
+ const handleFilterResetClick = () => {
+ if (hasValue(resultDefaultFilter)) {
+ handleFilterChange(resultDefaultFilter);
+ } else {
+ handleFilterChange(DEFAULT_FILTER);
+ }
+ };
- this.setState({activeTab: index});
- }
+ const handleActivateTab = index => {
+ handleInteraction();
+ setActiveTab(index);
+ };
- handleAddToAssets() {
- const {gmp, showSuccessMessage, entity, reportFilter: filter} = this.props;
+ const handleAddToAssets = () => {
+ const {showSuccessMessage, reportFilter: filter} = props;
- this.handleInteraction();
+ handleInteraction();
gmp.auditreport.addAssets(entity, {filter}).then(() => {
showSuccessMessage(
@@ -242,55 +263,43 @@ class DeltaAuditReportDetails extends React.Component {
'Report content added to Assets with QoD>=70% and Overrides enabled.',
),
);
- this.reload();
- }, this.handleError);
- }
+ reload();
+ }, handleError);
+ };
- handleRemoveFromAssets() {
- const {gmp, showSuccessMessage, entity, reportFilter: filter} = this.props;
+ const handleRemoveFromAssets = () => {
+ const {showSuccessMessage, reportFilter: filter} = props;
- this.handleInteraction();
+ handleInteraction();
gmp.auditreport.removeAssets(entity, {filter}).then(() => {
showSuccessMessage(_('Report content removed from Assets.'));
- this.reload();
- }, this.handleError);
- }
+ reload();
+ }, handleError);
+ };
- handleFilterEditClick() {
- this.handleInteraction();
+ const handleFilterEditClick = () => {
+ handleInteraction();
- this.setState({showFilterDialog: true});
- }
+ setShowFilterDialog(true);
+ };
- handleFilterDialogClose() {
- this.handleInteraction();
+ const handleFilterDialogClose = () => {
+ handleInteraction();
+ setShowFilterDialog(false);
+ };
- this.setState({showFilterDialog: false});
- }
+ const handleOpenDownloadReportDialog = () => {
+ setShowDownloadReportDialog(true);
+ };
- handleOpenDownloadReportDialog() {
- this.setState({
- showDownloadReportDialog: true,
- });
- }
-
- handleCloseDownloadReportDialog() {
- this.setState({showDownloadReportDialog: false});
- }
-
- handleReportDownload(state) {
- const {
- deltaReportId,
- entity,
- gmp,
- reportComposerDefaults,
- reportExportFileName,
- reportFilter,
- reportFormats = [],
- username,
- onDownload,
- } = this.props;
+ const handleCloseDownloadReportDialog = () => {
+ setShowDownloadReportDialog(false);
+ };
+
+ const handleReportDownload = state => {
+ const {reportFilter, onDownload} = props;
+ // eslint-disable-next-line no-shadow
const {includeNotes, includeOverrides, reportFormatId, storeAsDefault} =
state;
@@ -305,18 +314,18 @@ class DeltaAuditReportDetails extends React.Component {
includeNotes,
includeOverrides,
};
- this.props.saveReportComposerDefaults(defaults);
+ dispatch(saveReportComposerDefaults(gmp)(defaults));
}
- const report_format = reportFormats.find(
- format => reportFormatId === format.id,
- );
+ const report_format = reportFormats
+ ? reportFormats.find(format => reportFormatId === format.id)
+ : undefined;
const extension = isDefined(report_format)
? report_format.extension
: 'unknown'; // unknown should never happen but we should be save here
- this.handleInteraction();
+ handleInteraction();
return gmp.auditreport
.download(entity, {
@@ -325,7 +334,7 @@ class DeltaAuditReportDetails extends React.Component {
filter: newFilter,
})
.then(response => {
- this.setState({showDownloadReportDialog: false});
+ setShowDownloadReportDialog(false);
const {data} = response;
const filename = generateFilename({
creationTime: entity.creationTime,
@@ -333,290 +342,140 @@ class DeltaAuditReportDetails extends React.Component {
fileNameFormat: reportExportFileName,
id: entity.id,
modificationTime: entity.modificationTime,
- reportFormat: report_format.name,
+ reportFormat: report_format?.name,
resourceName: entity.task.name,
resourceType: 'report',
username,
});
onDownload({filename, data});
- }, this.handleError);
- }
-
- handleTlsCertificateDownload(cert) {
- const {onDownload} = this.props;
-
- const {data, serial} = cert;
-
- this.handleInteraction();
-
- onDownload({
- filename: 'tls-cert-' + serial + '.pem',
- data: create_pem_certificate(data),
- });
- }
-
- handleFilterCreated(filter) {
- this.handleInteraction();
- this.load(filter);
- this.props.loadFilters();
- }
-
- handleFilterAddLogLevel() {
- const {reportFilter} = this.props;
- let levels = reportFilter.get('levels', '');
-
- this.handleInteraction();
-
- if (!levels.includes('g')) {
- levels += 'g';
- const lfilter = reportFilter.copy();
- lfilter.set('levels', levels);
- this.load(lfilter);
- }
- }
-
- handleFilterRemoveSeverity() {
- const {reportFilter} = this.props;
-
- this.handleInteraction();
+ }, handleError);
+ };
- if (reportFilter.has('severity')) {
- const lfilter = reportFilter.copy();
- lfilter.delete('severity');
- this.load(lfilter);
- }
- }
+ const handleFilterCreated = filter => {
+ handleInteraction();
+ load(filter);
+ dispatch(loadFilters(gmp)(RESULTS_FILTER_FILTER));
+ };
- handleFilterDecreaseMinQoD() {
- const {reportFilter} = this.props;
+ const handleFilterDecreaseMinQoD = () => {
+ const {reportFilter} = props;
- this.handleInteraction();
+ handleInteraction();
if (reportFilter.has('min_qod')) {
const lfilter = reportFilter.copy();
lfilter.set('min_qod', 30);
- this.load(lfilter);
+ load(lfilter);
}
- }
+ };
- handleSortChange(name, sortField) {
- this.handleInteraction();
+ const handleSortChange = (name, sortField) => {
+ handleInteraction();
- const prev = this.state.sorting[name];
+ const prev = sorting[name];
const sortReverse =
sortField === prev.sortField ? !prev.sortReverse : false;
- this.setState({
- sorting: {
- ...this.state.sorting,
- [name]: {
- sortField,
- sortReverse,
- },
+ const newSorting = {
+ ...sorting,
+ [name]: {
+ sortField,
+ sortReverse,
},
- });
- }
+ };
+ setSorting(newSorting);
+ };
- handleInteraction() {
- const {onInteraction} = this.props;
- if (isDefined(onInteraction)) {
- onInteraction();
- }
- }
+ const handleInteraction = () => dispatch(renewSessionTimeout(gmp)());
- loadTarget() {
- const {entity} = this.props;
+ const loadTarget = () => {
const target = getTarget(entity);
+ return gmp.target.get({id: target.id});
+ };
+
+ const {reportFilter, showError, showErrorMessage, showSuccessMessage} = props;
+
+ const {report} = entity || {};
- return this.props.loadTarget(target.id);
- }
-
- render() {
- const {
- entity,
- entityError,
- filters = [],
- isLoading,
- reportFilter,
- reportFormats,
- reportId,
- onInteraction,
- reportComposerDefaults,
- showError,
- showErrorMessage,
- showSuccessMessage,
- } = this.props;
- const {
- activeTab,
- isUpdating = false,
- showFilterDialog,
- showDownloadReportDialog,
- sorting,
- storeAsDefault,
- } = this.state;
-
- const {report} = entity || {};
-
- return (
-
-
- {({edit}) => (
-
- this.loadTarget().then(response => edit(response.data))
- }
- onTlsCertificateDownloadClick={this.handleTlsCertificateDownload}
- showError={showError}
- showErrorMessage={showErrorMessage}
- showSuccessMessage={showSuccessMessage}
- />
- )}
-
- {showFilterDialog && (
-
+
+ {({edit}) => (
+
+ loadTarget().then(response => edit(response.data))
+ }
+ showError={showError}
+ showErrorMessage={showErrorMessage}
+ showSuccessMessage={showSuccessMessage}
/>
)}
- {showDownloadReportDialog && (
-
- )}
-
- );
- }
-}
+
+ {showFilterDialog && (
+
+ )}
+ {showDownloadReportDialog && (
+
+ )}
+
+ );
+};
DeltaAuditReportDetails.propTypes = {
defaultFilter: PropTypes.filter,
- deltaReportId: PropTypes.id,
- entity: PropTypes.model,
- entityError: PropTypes.object,
- filters: PropTypes.array,
- gmp: PropTypes.gmp.isRequired,
- isLoading: PropTypes.bool.isRequired,
- loadFilters: PropTypes.func.isRequired,
- loadReport: PropTypes.func.isRequired,
- loadReportComposerDefaults: PropTypes.func.isRequired,
- loadReportFormats: PropTypes.func.isRequired,
- loadReportIfNeeded: PropTypes.func.isRequired,
- loadSettings: PropTypes.func.isRequired,
- loadTarget: PropTypes.func.isRequired,
location: PropTypes.object.isRequired,
- match: PropTypes.object.isRequired,
reload: PropTypes.func.isRequired,
- reportComposerDefaults: PropTypes.object,
- reportExportFileName: PropTypes.string,
reportFilter: PropTypes.filter,
- reportFormats: PropTypes.array,
- reportId: PropTypes.id,
- resultDefaultFilter: PropTypes.filter,
- saveReportComposerDefaults: PropTypes.func.isRequired,
showError: PropTypes.func.isRequired,
showErrorMessage: PropTypes.func.isRequired,
showSuccessMessage: PropTypes.func.isRequired,
target: PropTypes.model,
username: PropTypes.string,
onDownload: PropTypes.func.isRequired,
- onInteraction: PropTypes.func.isRequired,
-};
-
-const mapDispatchToProps = (dispatch, {gmp}) => {
- return {
- onInteraction: () => dispatch(renewSessionTimeout(gmp)()),
- loadFilters: () => dispatch(loadFilters(gmp)(RESULTS_FILTER_FILTER)),
- loadSettings: () => dispatch(loadUserSettingDefaults(gmp)()),
- loadTarget: targetId => gmp.target.get({id: targetId}),
- loadReportFormats: () =>
- dispatch(loadReportFormats(gmp)(REPORT_FORMATS_FILTER)),
- loadReport: (id, deltaId, filter) =>
- dispatch(loadDeltaAuditReport(gmp)(id, deltaId, filter)),
- loadReportIfNeeded: (id, deltaId, filter) =>
- dispatch(loadDeltaAuditReport(gmp)(id, deltaId, filter)),
- loadReportComposerDefaults: () =>
- dispatch(loadReportComposerDefaults(gmp)()),
- loadUserSettingDefaultFilter: () =>
- dispatch(loadUserSettingsDefaultFilter(gmp)('result')),
- saveReportComposerDefaults: reportComposerDefaults =>
- dispatch(saveReportComposerDefaults(gmp)(reportComposerDefaults)),
- };
-};
-
-const mapStateToProps = (rootState, {match}) => {
- const {id, deltaid} = match.params;
- const filterSel = filterSelector(rootState);
- const deltaSel = deltaAuditReportSelector(rootState);
- const reportFormatsSel = reportFormatsSelector(rootState);
- const userDefaultsSelector = getUserSettingsDefaults(rootState);
- const userDefaultFilterSel = getUserSettingsDefaultFilter(
- rootState,
- 'result',
- );
- const username = getUsername(rootState);
- const entity = deltaSel.getEntity(id, deltaid);
- const entityError = deltaSel.getError(id, deltaid);
-
- return {
- deltaReportId: deltaid,
- entity,
- entityError,
- filters: filterSel.getAllEntities(RESULTS_FILTER_FILTER),
- isLoading: !isDefined(entity),
- reportExportFileName: userDefaultsSelector.getValueByName(
- 'reportexportfilename',
- ),
- reportFilter: getFilter(entity),
- reportFormats: reportFormatsSel.getAllEntities(REPORT_FORMATS_FILTER),
- reportId: id,
- reportComposerDefaults: getReportComposerDefaults(rootState),
- resultDefaultFilter: userDefaultFilterSel.getFilter('result'),
- username,
- };
};
const reloadInterval = report =>
@@ -625,14 +484,7 @@ const reloadInterval = report =>
: NO_RELOAD; // report doesn't change anymore. no need to reload
const load =
- ({
- defaultFilter,
- reportId,
- deltaReportId,
- loadReport,
- loadReportIfNeeded,
- reportFilter,
- }) =>
+ ({defaultFilter, reportId, deltaReportId, dispatch, gmp, reportFilter}) =>
filter => {
if (!hasValue(filter)) {
// use loaded filter after initial loading
@@ -654,45 +506,65 @@ const load =
// sort term will be handled by GSA in the browser)
filter.delete('sort-reverse');
filter.set('sort', 'name');
- return loadReportIfNeeded(reportId, deltaReportId, filter).then(() =>
- loadReport(reportId, deltaReportId, filter),
+ return dispatch(
+ loadDeltaAuditReport(gmp)(reportId, deltaReportId, filter),
+ ).then(() =>
+ dispatch(loadDeltaAuditReport(gmp)(reportId, deltaReportId, filter)),
);
};
-const DeltaAuditReportDetailsWrapper = ({
- defaultFilter,
- reportFilter,
- ...props
-}) => (
- reloadInterval(props.entity)}
- >
- {({reload}) => (
-
- )}
-
-);
+const DeltaAuditReportDetailsWrapper = ({defaultFilter, ...props}) => {
+ const gmp = useGmp();
+ const dispatch = useDispatch();
+ const match = useRouteMatch();
+
+ const {id: reportId, deltaid: deltaReportId} = match.params;
+ const deltaSel = useSelector(deltaAuditReportSelector, shallowEqual);
+ const entity = deltaSel.getEntity(reportId, deltaReportId);
+ const reportFilter = getFilter(entity);
+
+ return (
+ reloadInterval(entity)}
+ >
+ {({reload}) => (
+
+ )}
+
+ );
+};
DeltaAuditReportDetailsWrapper.propTypes = {
defaultFilter: PropTypes.filter,
- entity: PropTypes.model,
- gmp: PropTypes.gmp.isRequired,
- reportFilter: PropTypes.filter,
};
export default compose(
- withGmp,
withDialogNotification,
withDownload,
- connect(mapStateToProps, mapDispatchToProps),
)(DeltaAuditReportDetailsWrapper);
// vim: set ts=2 sw=2 tw=80:
diff --git a/src/web/pages/reports/auditdetailscontent.js b/src/web/pages/reports/auditdetailscontent.js
index 9447230fd3..6e2f4d8772 100644
--- a/src/web/pages/reports/auditdetailscontent.js
+++ b/src/web/pages/reports/auditdetailscontent.js
@@ -56,7 +56,7 @@ import EntityInfo from 'web/entity/info';
import EntityTags from 'web/entity/tags';
import PropTypes from 'web/utils/proptypes';
-import withGmp from 'web/utils/withGmp';
+import useGmp from 'web/utils/useGmp';
import ErrorsTab from './details/errorstab';
import HostsTab from './details/hoststab';
@@ -77,7 +77,6 @@ const PageContent = ({
entity,
errorsCounts,
filters,
- gmp,
hostsCounts,
isLoading = true,
isLoadingFilters = true,
@@ -99,12 +98,10 @@ const PageContent = ({
onAddToAssetsClick,
onTlsCertificateDownloadClick,
onError,
- onFilterAddLogLevelClick,
onFilterChanged,
onFilterCreated,
onFilterDecreaseMinQoDClick,
onFilterEditClick,
- onFilterRemoveSeverityClick,
onFilterRemoveClick,
onFilterResetClick,
onInteraction,
@@ -120,11 +117,12 @@ const PageContent = ({
const userTags = hasReport ? report.userTags : undefined;
const userTagsCount = isDefined(userTags) ? userTags.length : 0;
+ const gmp = useGmp();
const {
errors = {},
hosts = {},
- operatingsystems = {},
+ operatingSystems = {},
results = {},
tlsCertificates = {},
timestamp,
@@ -284,9 +282,7 @@ const PageContent = ({
reportResultsCounts={resultsCounts}
sortField={sorting.results.sortField}
sortReverse={sorting.results.sortReverse}
- onFilterAddLogLevelClick={onFilterAddLogLevelClick}
onFilterDecreaseMinQoDClick={onFilterDecreaseMinQoDClick}
- onFilterRemoveSeverityClick={onFilterRemoveSeverityClick}
onFilterEditClick={onFilterEditClick}
onFilterRemoveClick={onFilterRemoveClick}
onInteraction={onInteraction}
@@ -339,8 +335,8 @@ const PageContent = ({
) : (
.
*/
-import React from 'react';
+import React, {useEffect, useState} from 'react';
-import {connect} from 'react-redux';
+import {useDispatch, useSelector, shallowEqual} from 'react-redux';
+
+import {useRouteMatch} from 'react-router-dom';
import _ from 'gmp/locale';
@@ -85,6 +87,7 @@ import Page from './auditdetailscontent';
import FilterDialog from './detailsfilterdialog';
import {pageFilter as setPageFilter} from 'web/store/pages/actions';
import getPage from 'web/store/pages/selectors';
+import useGmp from 'web/utils/useGmp';
const log = logger.getLogger('web.pages.auditreport.detailspage');
@@ -98,6 +101,8 @@ export const AUDIT_REPORT_RESET_FILTER = RESET_FILTER.copy()
const REPORT_FORMATS_FILTER = Filter.fromString('active=1 and trust=1 rows=-1');
+const getReportPageName = id => `report-${id}`;
+
const getTarget = (entity = {}) => {
const {report = {}} = entity;
const {task = {}} = report;
@@ -109,127 +114,127 @@ const getFilter = (entity = {}) => {
return report.filter;
};
-class ReportDetails extends React.Component {
- constructor(...args) {
- super(...args);
-
- this.state = {
- activeTab: 0,
- showFilterDialog: false,
- showDownloadReportDialog: false,
- sorting: {
- results: {
- sortField: 'compliant',
- sortReverse: true,
- },
- hosts: {
- sortField: 'compliant',
- sortReverse: true,
- },
- os: {
- sortField: 'compliant',
- sortReverse: true,
- },
- tlscerts: {
- sortField: 'dn',
- sortReverse: false,
- },
- errors: {
- sortField: 'error',
- sortReverse: false,
- },
- },
- };
+const ReportDetails = props => {
+ const [activeTab, setActiveTab] = useState(0);
+ const [showFilterDialog, setShowFilterDialog] = useState(false);
+ const [showDownloadReportDialog, setShowDownloadReportDialog] =
+ useState(false);
+ const [sorting, setSorting] = useState({
+ results: {
+ sortField: 'compliant',
+ sortReverse: true,
+ },
+ hosts: {
+ sortField: 'compliant',
+ sortReverse: true,
+ },
+ os: {
+ sortField: 'compliant',
+ sortReverse: true,
+ },
+ tlscerts: {
+ sortField: 'dn',
+ sortReverse: false,
+ },
+ errors: {
+ sortField: 'error',
+ sortReverse: false,
+ },
+ });
+
+ const [entity, setEntity] = useState(undefined);
+ const [resultsCounts, setResultsCounts] = useState(undefined);
+ const [hostsCounts, setHostsCounts] = useState(undefined);
+ const [operatingSystemsCounts, setOperatingSystemsCounts] =
+ useState(undefined);
+ const [tlsCertificatesCounts, setTlsCertificatesCounts] = useState(undefined);
+ const [reportFormatId, setReportFormatId] = useState(undefined);
+ const [errorsCounts, setErrorsCounts] = useState(undefined);
+ const [reportFilter, setReportFilter] = useState(undefined);
+ const [isUpdating, setIsUpdating] = useState(false);
+ // storeAsDefault is set in SaveDialogContent
+ // eslint-disable-next-line no-unused-vars
+ const [storeAsDefault, setStoreAsDefault] = useState(undefined);
+
+ const gmp = useGmp();
+ const dispatch = useDispatch();
+ const match = useRouteMatch();
+ const {id: reportId} = match.params;
+
+ const pSelector = useSelector(getPage, shallowEqual);
+ const pageFilter = pSelector?.getFilter(getReportPageName(reportId));
+
+ const [selectedEntity, reportError, isLoading] = useSelector(state => {
+ const reportSel = auditReportSelector(state);
+ return [
+ reportSel?.getEntity(reportId, pageFilter),
+ reportSel?.getEntityError(reportId, pageFilter),
+ reportSel?.isLoadingEntity(reportId, pageFilter),
+ ];
+ }, shallowEqual);
+
+ const userDefaultsSelector = useSelector(
+ getUserSettingsDefaults,
+ shallowEqual,
+ );
+ const reportExportFileName = userDefaultsSelector?.getValueByName(
+ 'reportexportfilename',
+ );
+
+ const reportFormatsSel = useSelector(reportFormatsSelector);
+ const reportFormats = reportFormatsSel?.getAllEntities(REPORT_FORMATS_FILTER);
+ const reportComposerDefaults = useSelector(getReportComposerDefaults);
+ const userDefaultFilterSel = useSelector(
+ rootState => getUserSettingsDefaultFilter(rootState, 'result'),
+ shallowEqual,
+ );
+ const resultDefaultFilter = userDefaultFilterSel?.getFilter();
+ const username = useSelector(getUsername);
+
+ useEffect(() => {
+ dispatch(loadUserSettingDefaults(gmp)());
+ dispatch(loadFilters(gmp)(RESULTS_FILTER_FILTER));
+ dispatch(loadReportFormats(gmp)(REPORT_FORMATS_FILTER));
+ dispatch(loadReportComposerDefaults(gmp)());
+
+ if (isDefined(selectedEntity)) {
+ setEntity(entity);
+ updateReportCounts(selectedEntity);
+ setReportFilter(props.reportFilter);
+ setIsUpdating(false);
+ } else {
+ setIsUpdating(true);
+ }
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, []);
- this.handleActivateTab = this.handleActivateTab.bind(this);
- this.handleAddToAssets = this.handleAddToAssets.bind(this);
- this.handleChanged = this.handleChanged.bind(this);
- this.handleError = this.handleError.bind(this);
- this.handleFilterAddLogLevel = this.handleFilterAddLogLevel.bind(this);
- this.handleFilterChange = this.handleFilterChange.bind(this);
- this.handleFilterDecreaseMinQoD =
- this.handleFilterDecreaseMinQoD.bind(this);
- this.handleFilterCreated = this.handleFilterCreated.bind(this);
- this.handleFilterEditClick = this.handleFilterEditClick.bind(this);
- this.handleFilterRemoveSeverity =
- this.handleFilterRemoveSeverity.bind(this);
- this.handleFilterRemoveClick = this.handleFilterRemoveClick.bind(this);
- this.handleFilterResetClick = this.handleFilterResetClick.bind(this);
- this.handleRemoveFromAssets = this.handleRemoveFromAssets.bind(this);
- this.handleReportDownload = this.handleReportDownload.bind(this);
- this.handleTlsCertificateDownload =
- this.handleTlsCertificateDownload.bind(this);
- this.handleFilterDialogClose = this.handleFilterDialogClose.bind(this);
- this.handleSortChange = this.handleSortChange.bind(this);
-
- this.loadTarget = this.loadTarget.bind(this);
- this.handleOpenDownloadReportDialog =
- this.handleOpenDownloadReportDialog.bind(this);
- this.handleCloseDownloadReportDialog =
- this.handleCloseDownloadReportDialog.bind(this);
- }
-
- static getDerivedStateFromProps(props, state) {
- if (isDefined(props.entity)) {
+ useEffect(() => {
+ if (isDefined(selectedEntity)) {
// update only if a new report is available to avoid having no report
// when the filter changes
-
- const {report = {}} = props.entity;
- const {
- results = {},
- hosts = {},
- operatingsystems = {},
- tlsCertificates = {},
- errors = {},
- } = report;
-
- return {
- entity: props.entity,
-
- resultsCounts: isDefined(results.counts)
- ? results.counts
- : state.resultsCounts,
- hostsCounts: isDefined(hosts.counts) ? hosts.counts : state.hostsCounts,
- operatingSystemsCounts: isDefined(operatingsystems.counts)
- ? operatingsystems.counts
- : state.operatingSystemsCounts,
- tlsCertificatesCounts: isDefined(tlsCertificates.counts)
- ? tlsCertificates.counts
- : state.tlsCertificatesCounts,
- errorsCounts: isDefined(errors.counts)
- ? errors.counts
- : state.errorsCounts,
- reportFilter: props.reportFilter,
- isUpdating: false,
- };
+ setEntity(selectedEntity);
+ updateReportCounts(selectedEntity);
+ setReportFilter(props.reportFilter);
+ setIsUpdating(false);
+ } else {
+ // report is not in the store and is currently loaded
+ setIsUpdating(true);
}
- // report is not in the store and is currently loaded
- return {
- isUpdating: true,
- };
- }
+ }, [selectedEntity, props.reportFilter]);
- componentDidMount() {
- this.props.loadSettings();
- this.props.loadFilters();
- this.props.loadReportFormats();
- this.props.loadReportComposerDefaults();
- }
-
- componentDidUpdate(prevProps) {
- const {reportFormats} = this.props;
+ useEffect(() => {
if (
- !isDefined(this.state.reportFormatId) &&
+ !isDefined(reportFormatId) &&
isDefined(reportFormats) &&
reportFormats.length > 0
) {
// set initial report format id if available
- const reportFormatId = first(reportFormats).id;
- if (isDefined(reportFormatId)) {
+ const initialReportFormatId = first(reportFormats).id;
+ if (isDefined(initialReportFormatId)) {
// ensure the report format id is only set if we really have one
// if no report format id is available we would create an infinite
// render loop here
- this.setState({reportFormatId});
+ setReportFormatId({initialReportFormatId});
} else {
// if there is no report format at all, throw a proper error message
// instead of just showing x is undefined JS stacktrace
@@ -243,134 +248,153 @@ class ReportDetails extends React.Component {
throw new Error(noReportFormatError);
}
}
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [reportFormats, reportFormatId]);
+
+ useEffect(() => {
+ load();
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [reportId]);
- if (prevProps.reportId !== this.props.reportId) {
- this.load();
+ const updateReportCounts = reportEntity => {
+ const {report = {}} = reportEntity;
+ const {
+ results = {},
+ hosts = {},
+ operatingSystems = {},
+ tlsCertificates = {},
+ errors = {},
+ } = report;
+
+ if (isDefined(results.counts)) {
+ setResultsCounts(results.counts);
}
- }
+ if (isDefined(hosts.counts)) {
+ setHostsCounts(hosts.counts);
+ }
+ if (isDefined(operatingSystems.counts)) {
+ setOperatingSystemsCounts(operatingSystems.counts);
+ }
+ if (isDefined(tlsCertificates.counts)) {
+ setTlsCertificatesCounts(tlsCertificates.counts);
+ }
+ if (isDefined(errors.counts)) {
+ setErrorsCounts(errors.counts);
+ }
+ };
- load(filter) {
+ const load = newFilter => {
log.debug('Loading report', {
- filter,
+ newFilter,
});
- const {reportFilter} = this.props;
+ const {reportFilter: filter} = props;
- this.setState({
- isUpdating: !isDefined(reportFilter) || !reportFilter.equals(filter), // show update indicator if filter has changed
- });
+ setIsUpdating(!isDefined(filter) || !filter.equals(newFilter)); // show update indicator if filter has changed
- this.props
- .reload(filter)
+ props
+ .reload(newFilter)
.then(() => {
- this.setState({isUpdating: false});
+ setIsUpdating(false);
})
.catch(() => {
- this.setState({isUpdating: false});
+ setIsUpdating(false);
});
- }
+ };
- reload() {
+ const reload = () => {
// reload data from backend
- this.load(this.props.reportFilter);
- }
+ load(props.reportFilter);
+ };
- handleChanged() {
- this.reload();
- }
+ const handleChanged = () => {
+ reload();
+ };
- handleError(error) {
- const {showError} = this.props;
+ const handleError = error => {
+ const {showError} = props;
log.error(error);
showError(error);
- }
-
- handleFilterChange(filter) {
- this.handleInteraction();
+ };
- this.load(filter);
- }
+ const handleFilterChange = filter => {
+ handleInteraction();
+ load(filter);
+ };
- handleFilterRemoveClick() {
- this.handleFilterChange(AUDIT_REPORT_RESET_FILTER);
- }
+ const handleFilterRemoveClick = () => {
+ handleFilterChange(AUDIT_REPORT_RESET_FILTER);
+ };
- handleFilterResetClick() {
- if (hasValue(this.props.resultDefaultFilter)) {
- this.handleFilterChange(this.props.resultDefaultFilter);
+ const handleFilterResetClick = () => {
+ if (hasValue(resultDefaultFilter)) {
+ handleFilterChange(resultDefaultFilter);
} else {
- this.handleFilterChange(DEFAULT_FILTER);
+ handleFilterChange(DEFAULT_FILTER);
}
- }
-
- handleActivateTab(index) {
- this.handleInteraction();
+ };
- this.setState({activeTab: index});
- }
+ const handleActivateTab = index => {
+ handleInteraction();
+ setActiveTab(index);
+ };
- handleAddToAssets() {
- const {gmp, showSuccessMessage, entity, reportFilter: filter} = this.props;
+ const handleAddToAssets = () => {
+ const {showSuccessMessage, reportFilter: filter} = props;
- this.handleInteraction();
+ handleInteraction();
- gmp.auditreport.addAssets(entity, {filter}).then(() => {
+ gmp.auditreport.addAssets(selectedEntity, {filter}).then(() => {
showSuccessMessage(
_(
'Report content added to Assets with QoD>=70% and Overrides enabled.',
),
);
- this.reload();
- }, this.handleError);
- }
+ reload();
+ }, handleError);
+ };
- handleRemoveFromAssets() {
- const {gmp, showSuccessMessage, entity, reportFilter: filter} = this.props;
+ const handleRemoveFromAssets = () => {
+ const {showSuccessMessage, reportFilter: filter} = props;
- this.handleInteraction();
+ handleInteraction();
- gmp.auditreport.removeAssets(entity, {filter}).then(() => {
+ gmp.auditreport.removeAssets(selectedEntity, {filter}).then(() => {
showSuccessMessage(_('Report content removed from Assets.'));
- this.reload();
- }, this.handleError);
- }
-
- handleFilterEditClick() {
- this.handleInteraction();
+ reload();
+ }, handleError);
+ };
- this.setState({showFilterDialog: true});
- }
+ const handleFilterEditClick = () => {
+ handleInteraction();
+ setShowFilterDialog(true);
+ };
- handleFilterDialogClose() {
- this.handleInteraction();
+ const handleFilterDialogClose = () => {
+ handleInteraction();
+ setShowFilterDialog(false);
+ };
- this.setState({showFilterDialog: false});
- }
+ const handleOpenDownloadReportDialog = () => {
+ setShowDownloadReportDialog(true);
+ };
- handleOpenDownloadReportDialog() {
- this.setState({
- showDownloadReportDialog: true,
- });
- }
+ const handleCloseDownloadReportDialog = () => {
+ setShowDownloadReportDialog(false);
+ };
- handleCloseDownloadReportDialog() {
- this.setState({showDownloadReportDialog: false});
- }
+ const handleReportDownload = state => {
+ const {reportFilter: filter, onDownload} = props;
- handleReportDownload(state) {
const {
- entity,
- gmp,
- reportComposerDefaults,
- reportExportFileName,
- reportFilter,
- reportFormats = [],
- username,
- onDownload,
- } = this.props;
- const {includeNotes, includeOverrides, reportFormatId, storeAsDefault} =
- state;
-
- const newFilter = reportFilter.copy();
+ includeNotes,
+ includeOverrides,
+ // eslint-disable-next-line no-shadow
+ reportFormatId,
+ // eslint-disable-next-line no-shadow
+ storeAsDefault,
+ } = state;
+
+ const newFilter = filter.copy();
newFilter.set('notes', includeNotes);
newFilter.set('overrides', includeOverrides);
@@ -381,288 +405,205 @@ class ReportDetails extends React.Component {
includeNotes,
includeOverrides,
};
- this.props.saveReportComposerDefaults(defaults);
+ dispatch(saveReportComposerDefaults(gmp)(defaults));
}
- const report_format = reportFormats.find(
- format => reportFormatId === format.id,
- );
+ const report_format = reportFormats
+ ? reportFormats.find(format => reportFormatId === format.id)
+ : undefined;
const extension = isDefined(report_format)
? report_format.extension
: 'unknown'; // unknown should never happen but we should be save here
- this.handleInteraction();
+ handleInteraction();
return gmp.auditreport
- .download(entity, {
+ .download(selectedEntity, {
reportFormatId,
filter: newFilter,
})
.then(response => {
- this.setState({showDownloadReportDialog: false});
+ setShowDownloadReportDialog(false);
const {data} = response;
const filename = generateFilename({
- creationTime: entity.creationTime,
+ creationTime: selectedEntity.creationTime,
extension,
fileNameFormat: reportExportFileName,
- id: entity.id,
- modificationTime: entity.modificationTime,
- reportFormat: report_format.name,
- resourceName: entity.task.name,
+ id: selectedEntity.id,
+ modificationTime: selectedEntity.modificationTime,
+ reportFormat: report_format?.name,
+ resourceName: selectedEntity.task.name,
resourceType: 'report',
username,
});
onDownload({filename, data});
- }, this.handleError);
- }
+ }, handleError);
+ };
- handleTlsCertificateDownload(cert) {
- const {onDownload} = this.props;
+ const handleTlsCertificateDownload = cert => {
+ const {onDownload} = props;
const {data, serial} = cert;
- this.handleInteraction();
+ handleInteraction();
onDownload({
filename: 'tls-cert-' + serial + '.pem',
mimetype: 'application/x-x509-ca-cert',
data: create_pem_certificate(data),
});
- }
-
- handleFilterCreated(filter) {
- this.handleInteraction();
- this.load(filter);
- this.props.loadFilters();
- }
-
- handleFilterAddLogLevel() {
- const {reportFilter} = this.props;
- let levels = reportFilter.get('levels', '');
-
- this.handleInteraction();
-
- if (!levels.includes('g')) {
- levels += 'g';
- const lfilter = reportFilter.copy();
- lfilter.set('levels', levels);
- this.load(lfilter);
- }
- }
-
- handleFilterRemoveSeverity() {
- const {reportFilter} = this.props;
-
- this.handleInteraction();
+ };
- if (reportFilter.has('severity')) {
- const lfilter = reportFilter.copy();
- lfilter.delete('severity');
- this.load(lfilter);
- }
- }
+ const handleFilterCreated = filter => {
+ handleInteraction();
+ load(filter);
+ dispatch(loadFilters(gmp)(RESULTS_FILTER_FILTER));
+ };
- handleFilterDecreaseMinQoD() {
- const {reportFilter} = this.props;
+ const handleFilterDecreaseMinQoD = () => {
+ const {reportFilter: filter} = props;
- this.handleInteraction();
+ handleInteraction();
- if (reportFilter.has('min_qod')) {
- const lfilter = reportFilter.copy();
+ if (filter.has('min_qod')) {
+ const lfilter = filter.copy();
lfilter.set('min_qod', 30);
- this.load(lfilter);
+ load(lfilter);
}
- }
+ };
- handleSortChange(name, sortField) {
- this.handleInteraction();
+ const handleSortChange = (name, sortField) => {
+ handleInteraction();
- const prev = this.state.sorting[name];
+ const prev = sorting[name];
const sortReverse =
sortField === prev.sortField ? !prev.sortReverse : false;
- this.setState({
- sorting: {
- ...this.state.sorting,
- [name]: {
- sortField,
- sortReverse,
- },
+ const newSort = {
+ ...sorting,
+ [name]: {
+ sortField,
+ sortReverse,
},
- });
- }
+ };
+ setSorting(newSort);
+ };
- handleInteraction() {
- const {onInteraction} = this.props;
- if (isDefined(onInteraction)) {
- onInteraction();
- }
- }
+ const handleInteraction = () => dispatch(renewSessionTimeout(gmp)());
- loadTarget() {
- const {entity} = this.props;
- const target = getTarget(entity);
+ const loadTarget = () => {
+ const target = getTarget(selectedEntity);
+ return gmp.target.get({id: target.id});
+ };
- return this.props.loadTarget(target.id);
- }
+ const {showError, showErrorMessage, showSuccessMessage} = props;
- render() {
- const {
- filters = [],
- gmp,
- isLoading,
- isLoadingFilters,
- pageFilter,
- reportError,
- reportFormats,
- reportId,
- onInteraction,
- reportComposerDefaults,
- showError,
- showErrorMessage,
- showSuccessMessage,
- } = this.props;
- const {
- activeTab,
- entity,
- errorsCounts,
- hostsCounts,
- isUpdating = false,
- operatingSystemsCounts,
- reportFilter,
- resultsCounts,
- showFilterDialog,
- showDownloadReportDialog,
- sorting,
- storeAsDefault,
- tlsCertificatesCounts,
- } = this.state;
+ const report = isDefined(entity) ? entity.report : undefined;
- const report = isDefined(entity) ? entity.report : undefined;
+ const threshold = gmp.settings.reportResultsThreshold;
- const threshold = gmp.settings.reportResultsThreshold;
+ const showThresholdMessage =
+ isDefined(report) && report.results.counts.filtered > threshold;
- const showThresholdMessage =
- isDefined(report) && report.results.counts.filtered > threshold;
+ const [filters, isLoadingFilters] = useSelector(state => {
+ const filterSel = filterSelector(state);
+ return [
+ filterSel?.getAllEntities(RESULTS_FILTER_FILTER),
+ filterSel?.isLoadingAllEntities(RESULTS_FILTER_FILTER),
+ ];
+ });
- return (
-
-
-
- {({edit}) => (
-
- this.loadTarget().then(response => edit(response.data))
- }
- onTlsCertificateDownloadClick={this.handleTlsCertificateDownload}
- showError={showError}
- showErrorMessage={showErrorMessage}
- showSuccessMessage={showSuccessMessage}
- />
- )}
-
- {showFilterDialog && (
-
+
+
+ {({edit}) => (
+
- )}
- {showDownloadReportDialog && (
-
+ loadTarget().then(response => edit(response.data))
+ }
+ onTlsCertificateDownloadClick={handleTlsCertificateDownload}
+ showError={showError}
+ showErrorMessage={showErrorMessage}
+ showSuccessMessage={showSuccessMessage}
/>
)}
-
- );
- }
-}
+
+ {showFilterDialog && (
+
+ )}
+ {showDownloadReportDialog && (
+
+ )}
+
+ );
+};
ReportDetails.propTypes = {
- entity: PropTypes.model,
- filter: PropTypes.filter,
- filters: PropTypes.array,
- gmp: PropTypes.gmp.isRequired,
- isLoading: PropTypes.bool,
- isLoadingFilters: PropTypes.bool,
- loadFilters: PropTypes.func.isRequired,
- loadReportComposerDefaults: PropTypes.func.isRequired,
- loadReportFormats: PropTypes.func.isRequired,
- loadSettings: PropTypes.func.isRequired,
- loadTarget: PropTypes.func.isRequired,
location: PropTypes.object.isRequired,
- match: PropTypes.object.isRequired,
- pageFilter: PropTypes.filter,
reload: PropTypes.func.isRequired,
- reportComposerDefaults: PropTypes.object,
- reportError: PropTypes.error,
- reportExportFileName: PropTypes.string,
reportFilter: PropTypes.filter,
- reportFormats: PropTypes.array,
- reportId: PropTypes.id,
- resultDefaultFilter: PropTypes.filter,
- saveReportComposerDefaults: PropTypes.func.isRequired,
showError: PropTypes.func.isRequired,
showErrorMessage: PropTypes.func.isRequired,
showSuccessMessage: PropTypes.func.isRequired,
target: PropTypes.model,
username: PropTypes.string,
onDownload: PropTypes.func.isRequired,
- onInteraction: PropTypes.func.isRequired,
};
const reloadInterval = report =>
@@ -675,10 +616,11 @@ const load =
defaultFilter,
reportId,
// eslint-disable-next-line no-shadow
- loadReportWithThreshold,
+ dispatch,
+ gmp,
+ match,
pageFilter,
reportFilter,
- updateFilter,
}) =>
filter => {
if (!hasValue(filter)) {
@@ -700,110 +642,72 @@ const load =
// use fallback filter
filter = DEFAULT_FILTER;
}
-
- updateFilter(filter);
- return loadReportWithThreshold(reportId, {filter});
+ dispatch(setPageFilter(getReportPageName(match.params.id), filter));
+ return dispatch(loadAuditReportWithThreshold(gmp)(reportId, {filter}));
};
-const ReportDetailsWrapper = ({reportFilter, ...props}) => (
-
- {({filter}) => (
- reloadInterval(props.entity)}
- >
- {({reload}) => (
-
- )}
-
- )}
-
-);
-
-ReportDetailsWrapper.propTypes = {
- entity: PropTypes.model,
- gmp: PropTypes.gmp.isRequired,
- reportFilter: PropTypes.filter,
- reportId: PropTypes.id.isRequired,
-};
-
-const getReportPageName = id => `report-${id}`;
-
-const mapDispatchToProps = (dispatch, {gmp, entity, match}) => ({
- onInteraction: () => dispatch(renewSessionTimeout(gmp)()),
- loadFilters: () => dispatch(loadFilters(gmp)(RESULTS_FILTER_FILTER)),
- loadSettings: () => dispatch(loadUserSettingDefaults(gmp)()),
- loadTarget: targetId => gmp.target.get({id: targetId}),
- loadReportFormats: () =>
- dispatch(loadReportFormats(gmp)(REPORT_FORMATS_FILTER)),
- loadReportWithThreshold: (id, options) =>
- dispatch(loadAuditReportWithThreshold(gmp)(id, options)),
- loadReportComposerDefaults: () => dispatch(loadReportComposerDefaults(gmp)()),
- saveReportComposerDefaults: reportComposerDefaults =>
- dispatch(saveReportComposerDefaults(gmp)(reportComposerDefaults)),
- updateFilter: f =>
- dispatch(setPageFilter(getReportPageName(match.params.id), f)),
-});
-
-const mapStateToProps = (rootState, {match}) => {
- const {id} = match.params;
- const filterSel = filterSelector(rootState);
- const reportSel = auditReportSelector(rootState);
- const reportFormatsSel = reportFormatsSelector(rootState);
- const userDefaultsSelector = getUserSettingsDefaults(rootState);
- const userDefaultFilterSel = getUserSettingsDefaultFilter(
- rootState,
- 'result',
- );
- const username = getUsername(rootState);
-
- const pSelector = getPage(rootState);
- const pageFilter = pSelector.getFilter(getReportPageName(id));
-
- const entity = reportSel.getEntity(id, pageFilter);
- const isLoading = reportSel.isLoadingEntity(id, pageFilter);
- const reportError = reportSel.getEntityError(id, pageFilter);
-
- const filters = filterSel.getAllEntities(RESULTS_FILTER_FILTER);
- const isLoadingFilters = filterSel.isLoadingAllEntities(
- RESULTS_FILTER_FILTER,
+const ReportDetailsWrapper = props => {
+ const dispatch = useDispatch();
+ const gmp = useGmp();
+ const match = useRouteMatch();
+
+ const {id: reportId} = match.params;
+ const reportSel = useSelector(auditReportSelector, shallowEqual);
+ const pSelector = useSelector(getPage, shallowEqual);
+
+ const pageFilter = pSelector.getFilter(getReportPageName(reportId));
+ const entity = reportSel.getEntity(reportId, pageFilter);
+ const reportFilter = getFilter(entity);
+
+ return (
+
+ {({filter}) => (
+ reloadInterval(entity)}
+ >
+ {({reload}) => (
+
+ )}
+
+ )}
+
);
-
- return {
- entity,
- filters,
- reportError,
- pageFilter,
- isLoading,
- isLoadingFilters,
- reportExportFileName: userDefaultsSelector.getValueByName(
- 'reportexportfilename',
- ),
- reportFilter: getFilter(entity),
- reportFormats: reportFormatsSel.getAllEntities(REPORT_FORMATS_FILTER),
- reportId: id,
- reportComposerDefaults: getReportComposerDefaults(rootState),
- resultDefaultFilter: userDefaultFilterSel.getFilter(),
- username,
- };
};
export default compose(
withGmp,
withDialogNotification,
withDownload,
- connect(mapStateToProps, mapDispatchToProps),
)(ReportDetailsWrapper);
// vim: set ts=2 sw=2 tw=80:
diff --git a/src/web/pages/reports/auditfilterdialog.js b/src/web/pages/reports/auditfilterdialog.js
index e9618b1367..b7ee5a41be 100644
--- a/src/web/pages/reports/auditfilterdialog.js
+++ b/src/web/pages/reports/auditfilterdialog.js
@@ -22,7 +22,7 @@ import {_l, _} from 'gmp/locale/lang';
import Layout from 'web/components/layout/layout';
import compose from 'web/utils/compose';
-import withCapabilities from 'web/utils/withCapabilities';
+import useCapabilities from 'web/utils/useCapabilities';
/* eslint-disable max-len */
@@ -71,7 +71,6 @@ const SORT_FIELDS = [
];
const AuditReportFilterDialogComponent = ({
- capabilities,
filter,
filterName,
filterstring,
@@ -87,6 +86,8 @@ const AuditReportFilterDialogComponent = ({
const handleRemoveCompliance = () =>
onFilterChange(filter.delete('report_compliance_levels'));
+ const capabilities = useCapabilities();
+
if (!filter) {
return null;
}
@@ -144,9 +145,6 @@ const AuditReportFilterDialogComponent = ({
AuditReportFilterDialogComponent.propTypes = FilterDialogPropTypes;
-export default compose(
- withCapabilities,
- withFilterDialog(),
-)(AuditReportFilterDialogComponent);
+export default compose(withFilterDialog())(AuditReportFilterDialogComponent);
// vim: set ts=2 sw=2 tw=80:
diff --git a/src/web/pages/reports/auditreportrow.js b/src/web/pages/reports/auditreportrow.js
index b922244eb1..de5684d7e4 100644
--- a/src/web/pages/reports/auditreportrow.js
+++ b/src/web/pages/reports/auditreportrow.js
@@ -139,10 +139,10 @@ const AuditRow = ({
- {report.compliance_count.yes.filtered}
- {report.compliance_count.no.filtered}
+ {report.complianceCounts.yes.filtered}
+ {report.complianceCounts.no.filtered}
- {report.compliance_count.incomplete.filtered}
+ {report.complianceCounts.incomplete.filtered}
diff --git a/src/web/pages/reports/auditreportslistpage.js b/src/web/pages/reports/auditreportslistpage.js
index 51f81fb81b..f7d64e24b4 100644
--- a/src/web/pages/reports/auditreportslistpage.js
+++ b/src/web/pages/reports/auditreportslistpage.js
@@ -16,7 +16,9 @@
* along with this program. If not, see .
*/
-import React from 'react';
+import React, {useEffect, useState} from 'react';
+
+import {useHistory} from 'react-router-dom';
import _ from 'gmp/locale';
@@ -68,46 +70,36 @@ const ToolBarIcons = () => (
);
-class Page extends React.Component {
- constructor(...args) {
- super(...args);
-
- this.state = {};
-
- this.handleReportDeltaSelect = this.handleReportDeltaSelect.bind(this);
- this.handleReportDeleteClick = this.handleReportDeleteClick.bind(this);
- this.handleTaskChange = this.handleTaskChange.bind(this);
- }
-
- static getDerivedStateFromProps(props, state) {
- const {filter} = props;
- const {selectedDeltaReport} = state;
+const AuditReportsPage = props => {
+ const [selectedDeltaReport, setSelectedDeltaReport] = useState(undefined);
+ const [beforeSelectFilter, setBeforeSelectFilter] = useState(undefined);
+ const history = useHistory();
+ useEffect(() => {
if (
isDefined(selectedDeltaReport) &&
- (!isDefined(filter) ||
- filter.get('task_id') !== selectedDeltaReport.task.id)
+ (!isDefined(props.filter) ||
+ props.filter.get('task_id') !== selectedDeltaReport.task.id)
) {
// filter has changed. reset delta report selection
- return {selectedDeltaReport: undefined};
+ setSelectedDeltaReport(undefined);
}
- return null;
- }
+ }, [props.filter, selectedDeltaReport]);
- handleReportDeltaSelect(report) {
- const {onFilterChanged} = this.props;
- const {selectedDeltaReport, beforeSelectFilter} = this.state;
+ const handleReportDeleteClick = report => {
+ const {onDelete} = props;
+ return onDelete(report);
+ };
+ const handleReportDeltaSelect = report => {
if (isDefined(selectedDeltaReport)) {
- const {history} = this.props;
-
onFilterChanged(beforeSelectFilter);
history.push(
'/auditreport/delta/' + selectedDeltaReport.id + '/' + report.id,
);
} else {
- const {filter = new Filter()} = this.props;
+ const {filter = new Filter()} = props;
onFilterChanged(
filter
@@ -115,60 +107,46 @@ class Page extends React.Component {
.set('first', 1) // reset to first page
.set('task_id', report.task.id),
);
-
- this.setState({
- beforeSelectFilter: filter,
- selectedDeltaReport: report,
- });
+ setSelectedDeltaReport(report);
+ setBeforeSelectFilter(filter);
}
- }
+ };
+
+ const {filter, onFilterChanged, onInteraction} = props;
+ return (
+
+
+ (
+
+ )}
+ dashboardControls={() => (
+
+ )}
+ filtersFilter={AUDIT_REPORTS_FILTER_FILTER}
+ filterEditDialog={AuditFilterDialog}
+ table={AuditReportsTable}
+ toolBarIcons={ToolBarIcons}
+ title={_('Audit Reports')}
+ sectionIcon={}
+ onInteraction={onInteraction}
+ onReportDeltaSelect={handleReportDeltaSelect}
+ onReportDeleteClick={handleReportDeleteClick}
+ />
+
+ );
+};
- handleReportDeleteClick(report) {
- const {onDelete} = this.props;
- return onDelete(report);
- }
-
- handleTaskChange(task_id) {
- this.setState({task_id});
- }
-
- render() {
- const {filter, onFilterChanged, onInteraction} = this.props;
- return (
-
-
- (
-
- )}
- dashboardControls={() => (
-
- )}
- filtersFilter={AUDIT_REPORTS_FILTER_FILTER}
- filterEditDialog={AuditFilterDialog}
- table={AuditReportsTable}
- toolBarIcons={ToolBarIcons}
- title={_('Audit Reports')}
- sectionIcon={}
- onInteraction={onInteraction}
- onReportDeltaSelect={this.handleReportDeltaSelect}
- onReportDeleteClick={this.handleReportDeleteClick}
- />
-
- );
- }
-}
-
-Page.propTypes = {
+AuditReportsPage.propTypes = {
filter: PropTypes.filter,
gmp: PropTypes.gmp.isRequired,
history: PropTypes.object.isRequired,
@@ -196,6 +174,6 @@ export default compose(
loadEntities,
reloadInterval: reportsReloadInterval,
}),
-)(Page);
+)(AuditReportsPage);
// vim: set ts=2 sw=2 tw=80:
diff --git a/src/web/pages/reports/auditreportstable.js b/src/web/pages/reports/auditreportstable.js
index a4660d3c2e..3ccbddaaad 100644
--- a/src/web/pages/reports/auditreportstable.js
+++ b/src/web/pages/reports/auditreportstable.js
@@ -21,18 +21,18 @@ import {_, _l} from 'gmp/locale/lang';
import {isDefined} from 'gmp/utils/identity';
-import PropTypes from '../../utils/proptypes.js';
+import PropTypes from 'web/utils/proptypes';
-import {createEntitiesFooter} from '../../entities/footer.js';
-import {createEntitiesTable} from '../../entities/table.js';
+import {createEntitiesFooter} from 'web/entities/footer';
+import {createEntitiesTable} from 'web/entities/table';
-import ComplianceState from '../../components/label/compliancestate.js';
+import ComplianceState from 'web/components/label/compliancestate';
-import TableHead from '../../components/table/head.js';
-import TableHeader from '../../components/table/header.js';
-import TableRow from '../../components/table/row.js';
+import TableHead from 'web/components/table/head';
+import TableHeader from 'web/components/table/header';
+import TableRow from 'web/components/table/row';
-import AuditReportRow from './auditreportrow.js';
+import AuditReportRow from './auditreportrow';
const Header = ({
actionsColumn,
diff --git a/src/web/pages/reports/deltadetailscontent.js b/src/web/pages/reports/deltadetailscontent.js
index 1c95f2e478..405c9af10d 100644
--- a/src/web/pages/reports/deltadetailscontent.js
+++ b/src/web/pages/reports/deltadetailscontent.js
@@ -83,7 +83,6 @@ const PageContent = ({
task,
onActivateTab,
onAddToAssetsClick,
- onTlsCertificateDownloadClick,
onError,
onFilterAddLogLevelClick,
onFilterChanged,
@@ -107,7 +106,7 @@ const PageContent = ({
const {
results = {},
- compliance_count = {},
+ complianceCounts = {},
result_count = {},
timestamp,
scan_run_status,
@@ -145,7 +144,7 @@ const PageContent = ({
);
- const {filtered} = audit ? compliance_count : result_count;
+ const {filtered} = audit ? complianceCounts : result_count;
return (
@@ -276,13 +275,13 @@ PageContent.propTypes = {
onActivateTab: PropTypes.func.isRequired,
onAddToAssetsClick: PropTypes.func.isRequired,
onError: PropTypes.func.isRequired,
- onFilterAddLogLevelClick: PropTypes.func.isRequired,
+ onFilterAddLogLevelClick: PropTypes.func,
onFilterChanged: PropTypes.func.isRequired,
onFilterCreated: PropTypes.func.isRequired,
onFilterDecreaseMinQoDClick: PropTypes.func.isRequired,
onFilterEditClick: PropTypes.func.isRequired,
onFilterRemoveClick: PropTypes.func.isRequired,
- onFilterRemoveSeverityClick: PropTypes.func.isRequired,
+ onFilterRemoveSeverityClick: PropTypes.func,
onFilterResetClick: PropTypes.func.isRequired,
onInteraction: PropTypes.func.isRequired,
onRemoveFromAssetsClick: PropTypes.func.isRequired,
@@ -290,7 +289,6 @@ PageContent.propTypes = {
onSortChange: PropTypes.func.isRequired,
onTagSuccess: PropTypes.func.isRequired,
onTargetEditClick: PropTypes.func.isRequired,
- onTlsCertificateDownloadClick: PropTypes.func.isRequired,
};
export default PageContent;
diff --git a/src/web/pages/reports/deltadetailspage.js b/src/web/pages/reports/deltadetailspage.js
index f7f96e73ad..c0b59e598d 100644
--- a/src/web/pages/reports/deltadetailspage.js
+++ b/src/web/pages/reports/deltadetailspage.js
@@ -71,7 +71,6 @@ import {
getUsername,
} from 'web/store/usersettings/selectors';
-import {create_pem_certificate} from 'web/utils/cert';
import compose from 'web/utils/compose';
import {generateFilename} from 'web/utils/render';
import PropTypes from 'web/utils/proptypes';
@@ -165,8 +164,6 @@ class DeltaReportDetails extends React.Component {
this.handleFilterResetClick = this.handleFilterResetClick.bind(this);
this.handleRemoveFromAssets = this.handleRemoveFromAssets.bind(this);
this.handleReportDownload = this.handleReportDownload.bind(this);
- this.handleTlsCertificateDownload =
- this.handleTlsCertificateDownload.bind(this);
this.handleFilterDialogClose = this.handleFilterDialogClose.bind(this);
this.handleSortChange = this.handleSortChange.bind(this);
@@ -371,19 +368,6 @@ class DeltaReportDetails extends React.Component {
}, this.handleError);
}
- handleTlsCertificateDownload(cert) {
- const {onDownload} = this.props;
-
- const {data, serial} = cert;
-
- this.handleInteraction();
-
- onDownload({
- filename: 'tls-cert-' + serial + '.pem',
- data: create_pem_certificate(data),
- });
- }
-
handleFilterCreated(filter) {
this.handleInteraction();
this.load(filter);
@@ -523,7 +507,6 @@ class DeltaReportDetails extends React.Component {
onTargetEditClick={() =>
this.loadTarget().then(response => edit(response.data))
}
- onTlsCertificateDownloadClick={this.handleTlsCertificateDownload}
showError={showError}
showErrorMessage={showErrorMessage}
showSuccessMessage={showSuccessMessage}
diff --git a/src/web/pages/reports/details/emptyresultsreport.js b/src/web/pages/reports/details/emptyresultsreport.js
index 0d44c9bd6c..1ae0e94b73 100644
--- a/src/web/pages/reports/details/emptyresultsreport.js
+++ b/src/web/pages/reports/details/emptyresultsreport.js
@@ -68,7 +68,7 @@ const EmptyResultsReport = ({
- {!levels.includes('g') && (
+ {!levels.includes('g') && isDefined(onFilterAddLogLevelClick) && (
}
title={_('Log messages are currently excluded.')}
@@ -78,7 +78,7 @@ const EmptyResultsReport = ({
)}
- {has_severity_filter && (
+ {has_severity_filter && isDefined(onFilterRemoveSeverityClick) && (
}
title={_(
@@ -129,11 +129,11 @@ const EmptyResultsReport = ({
EmptyResultsReport.propTypes = {
all: PropTypes.number.isRequired,
filter: PropTypes.filter.isRequired,
- onFilterAddLogLevelClick: PropTypes.func.isRequired,
+ onFilterAddLogLevelClick: PropTypes.func,
onFilterDecreaseMinQoDClick: PropTypes.func.isRequired,
onFilterEditClick: PropTypes.func.isRequired,
onFilterRemoveClick: PropTypes.func.isRequired,
- onFilterRemoveSeverityClick: PropTypes.func.isRequired,
+ onFilterRemoveSeverityClick: PropTypes.func,
};
export default EmptyResultsReport;
diff --git a/src/web/pages/reports/details/hoststab.js b/src/web/pages/reports/details/hoststab.js
index 9f0fefacd0..9a8052619a 100644
--- a/src/web/pages/reports/details/hoststab.js
+++ b/src/web/pages/reports/details/hoststab.js
@@ -49,13 +49,13 @@ const hostsSortFunctions = {
start: makeCompareDate(entity => entity.start),
end: makeCompareDate(entity => entity.end),
total: makeCompareNumber(entity => entity.result_counts.total),
- compliance_yes: makeCompareNumber(entity => entity.compliance_counts.yes),
- compliance_no: makeCompareNumber(entity => entity.compliance_counts.no),
- compliance_incomplete: makeCompareNumber(
- entity => entity.compliance_counts.incomplete,
+ complianceYes: makeCompareNumber(entity => entity.complianceCounts.yes),
+ complianceNo: makeCompareNumber(entity => entity.complianceCounts.no),
+ complianceIncomplete: makeCompareNumber(
+ entity => entity.complianceCounts.incomplete,
),
- compliance_total: makeCompareNumber(entity => entity.compliance_counts.total),
- compliant: makeCompareString('host_compliance'),
+ complianceTotal: makeCompareNumber(entity => entity.complianceCounts.total),
+ compliant: makeCompareString('hostCompliance'),
};
const HostsTab = ({
diff --git a/src/web/pages/reports/details/hoststable.js b/src/web/pages/reports/details/hoststable.js
index e6e8a65a9d..02de322e39 100644
--- a/src/web/pages/reports/details/hoststable.js
+++ b/src/web/pages/reports/details/hoststable.js
@@ -122,7 +122,7 @@ const Header = ({
{
authSuccess,
details = {},
end,
- host_compliance,
+ hostCompliance,
ip,
result_counts = {},
- compliance_counts = {},
+ complianceCounts = {},
severity,
start,
portsCount,
@@ -333,30 +333,30 @@ const Row = ({entity, links = true, audit = false}) => {
{audit ? (
- {compliance_counts.yes}
+ {complianceCounts.yes}
) : (
{result_counts.high}
)}
{audit ? (
- {compliance_counts.no}
+ {complianceCounts.no}
) : (
{result_counts.warning}
)}
{audit ? (
- {compliance_counts.incomplete}
+ {complianceCounts.incomplete}
) : (
{result_counts.info}
)}
{!audit && {result_counts.log}}
{!audit && {result_counts.false_positive}}
{audit ? (
- {compliance_counts.total}
+ {complianceCounts.total}
) : (
{result_counts.total}
)}
{audit ? (
-
+
) : (
diff --git a/src/web/pages/reports/details/resultstab.js b/src/web/pages/reports/details/resultstab.js
index 5a36bed723..6a759de2ae 100644
--- a/src/web/pages/reports/details/resultstab.js
+++ b/src/web/pages/reports/details/resultstab.js
@@ -272,11 +272,11 @@ ResultsTab.propTypes = {
resultsError: PropTypes.error,
resultsFilter: PropTypes.filter,
status: PropTypes.string.isRequired,
- onFilterAddLogLevelClick: PropTypes.func.isRequired,
+ onFilterAddLogLevelClick: PropTypes.func,
onFilterDecreaseMinQoDClick: PropTypes.func.isRequired,
onFilterEditClick: PropTypes.func.isRequired,
onFilterRemoveClick: PropTypes.func.isRequired,
- onFilterRemoveSeverityClick: PropTypes.func.isRequired,
+ onFilterRemoveSeverityClick: PropTypes.func,
onTargetEditClick: PropTypes.func.isRequired,
};
diff --git a/src/web/pages/tasks/row.js b/src/web/pages/tasks/row.js
index 37496c76db..842b8c7b96 100644
--- a/src/web/pages/tasks/row.js
+++ b/src/web/pages/tasks/row.js
@@ -54,7 +54,7 @@ import Trend from './trend';
import {GREENBONE_SENSOR_SCANNER_TYPE} from 'gmp/models/scanner';
-const renderReport = (report, links) => {
+export const renderReport = (report, links) => {
if (!isDefined(report)) {
return null;
}
diff --git a/src/web/utils/theme.js b/src/web/utils/theme.js
index 6cbf026bcc..f7d572db79 100644
--- a/src/web/utils/theme.js
+++ b/src/web/utils/theme.js
@@ -37,10 +37,10 @@ const Theme = {
darkRed: '#c12c30', // used by: dialog errors font
errorRed: '#c83814', // used by: progressbar
- compliance_yes: '#4cb045',
- compliance_no: '#D80000',
- compliance_incomplete: 'orange',
- compliance_undefined: 'silver',
+ complianceYes: '#4cb045',
+ complianceNo: '#D80000',
+ complianceIncomplete: 'orange',
+ complianceUndefined: 'silver',
lightBlue: '#d6e6fd', // used by InfoPanel and dashboard hovering
mediumBlue: '#77acf7', // used by active/hovered items in Select