From 14e6ed2858e8cef93ba4d8f669851faab2955f4a Mon Sep 17 00:00:00 2001
From: Martin Michalik <62351699+xmicha82@users.noreply.github.com>
Date: Thu, 17 Oct 2024 11:24:02 +0200
Subject: [PATCH] fix(SystemCVEs): RHINENG-11464 inventory tab advisory filter
(#2149)
---
.../SmartComponents/SystemCves/SystemCves.js | 11 +++-
src/Helpers/Hooks.js | 50 +++++++++++++++
src/Utilities/AccountStatContextWrapper.js | 35 +++++++++++
src/Utilities/VulnerabilityRoutes.js | 62 ++++---------------
src/index.js | 15 ++++-
5 files changed, 120 insertions(+), 53 deletions(-)
create mode 100644 src/Utilities/AccountStatContextWrapper.js
diff --git a/src/Components/SmartComponents/SystemCves/SystemCves.js b/src/Components/SmartComponents/SystemCves/SystemCves.js
index 8f0fb4640..43f0a7a1f 100644
--- a/src/Components/SmartComponents/SystemCves/SystemCves.js
+++ b/src/Components/SmartComponents/SystemCves/SystemCves.js
@@ -95,7 +95,7 @@ export const SystemCVEs = ({
entity.id, systemCVEs, columns, linkToCustomerPortal
), [systemCVEs, systemCVEs.isLoading, entity.id, columns]);
const [urlParameters, setUrlParams] = useUrlParams(CVES_ALLOWED_PARAMS);
- const { includesCvesWithoutErrata } = useContext(AccountStatContext);
+ const { includesCvesWithoutErrata, isFederated } = useContext(AccountStatContext);
const downloadReport = format => {
const params = { ...parameters, system: entity.id };
@@ -128,10 +128,15 @@ export const SystemCVEs = ({
dispatch(changeSystemCVEsParameters(params));
};
+ const paramsWithoutKeys = (params, keys) => Object.fromEntries(Object.entries(params).filter((p) => !keys.includes(p[0])));
+
useEffect(() => {
apply(
- isEmpty(urlParameters) ?
- { advisory_available: 'true' }
+ isEmpty(paramsWithoutKeys(urlParameters, ['appName'])) ?
+ {
+ advisory_available: 'true',
+ ...isFederated ? { appName: 'vulnerabilities' } : {}
+ }
: urlParameters
);
diff --git a/src/Helpers/Hooks.js b/src/Helpers/Hooks.js
index 5e6d6f439..9b837482b 100644
--- a/src/Helpers/Hooks.js
+++ b/src/Helpers/Hooks.js
@@ -14,6 +14,7 @@ import ColumnManagementModal from '../Components/SmartComponents/Modals/ColumnMa
import useChrome from '@redhat-cloud-services/frontend-components/useChrome';
import { useFlag, useFlagsStatus } from '@unleash/proxy-client-react';
import { AccountStatContext } from '../Utilities/VulnerabilityRoutes';
+import { getRhelSystems, checkEdgePresence, getCveListByAccount } from './APIHelper';
export const useNotification = (config = {}) => {
const dispatch = useDispatch();
@@ -279,3 +280,52 @@ export const useHybridSystemFilterFlag = () => {
const shouldUseHybridSystemFilter = isEdgeParityEnabled && hasEdgeDevices;
return shouldUseHybridSystemFilter;
};
+
+export const useAccountStats = (isEdgeParityEnabled, setLoading, addNotification) => {
+ const [hasEdgeDevices, setHasEdgeDevices] = useState(true);
+ const [hasConventionalSystems, setHasConventionalSystems] = useState(true);
+ const [includesCvesWithoutErrata, setIncludesCvesWithoutErrata] = useState();
+ const [isAdvisoryAvailable, setAdvisoryAvailable] = useState();
+ const [hasAccess, setHasAccess] = useState(true);
+
+ useEffect(() => {
+ const fetchData = async () => {
+ try {
+ const rhelSystems = await getRhelSystems();
+ if (isEdgeParityEnabled) {
+ //if there is at least 1 edge device in the account level, not only in vulnerability
+ const edgeDevicePresent = await checkEdgePresence();
+ setHasEdgeDevices(edgeDevicePresent);
+ }
+
+ const { meta: {
+ cves_without_errata: cvesWithoutErrata, advisory_available: advisoryAvailable
+ } = {}
+ } = await getCveListByAccount({ limit: 1 });
+
+ setHasConventionalSystems(rhelSystems);
+ setIncludesCvesWithoutErrata(cvesWithoutErrata);
+ setAdvisoryAvailable(advisoryAvailable);
+ setLoading(false);
+ } catch (error) {
+ if (error.status === '403') {
+ setHasAccess(false);
+ }
+ else {
+ addNotification({
+ variant: 'danger',
+ autoDismiss: false,
+ msg: 'Failed to fetch systems',
+ description: error.detail
+ });
+ }
+
+ setLoading(false);
+ }
+ };
+
+ fetchData();
+ }, []);
+
+ return { hasEdgeDevices, hasConventionalSystems, includesCvesWithoutErrata, isAdvisoryAvailable, hasAccess };
+};
diff --git a/src/Utilities/AccountStatContextWrapper.js b/src/Utilities/AccountStatContextWrapper.js
new file mode 100644
index 000000000..529750e7f
--- /dev/null
+++ b/src/Utilities/AccountStatContextWrapper.js
@@ -0,0 +1,35 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import useFeatureFlag from './useFeatureFlag';
+import { useAccountStats, useNotification } from '../Helpers/Hooks';
+import { AccountStatContext } from './VulnerabilityRoutes';
+
+export const AccountStatContextWrapper = ({ children, setLoading, isFederated = false }) => {
+ const isEdgeParityEnabled = useFeatureFlag('vulnerability.edge_parity');
+ const [addNotification] = useNotification();
+
+ const {
+ hasConventionalSystems,
+ hasEdgeDevices,
+ includesCvesWithoutErrata,
+ isAdvisoryAvailable
+ } = useAccountStats(isEdgeParityEnabled, setLoading, addNotification);
+
+ return (
+
+ { children }
+
+ );
+};
+
+AccountStatContextWrapper.propTypes = {
+ children: PropTypes.func,
+ setLoading: PropTypes.func,
+ isFederated: PropTypes.bool
+};
diff --git a/src/Utilities/VulnerabilityRoutes.js b/src/Utilities/VulnerabilityRoutes.js
index e7fd7c8d1..87bda2d3a 100644
--- a/src/Utilities/VulnerabilityRoutes.js
+++ b/src/Utilities/VulnerabilityRoutes.js
@@ -1,7 +1,6 @@
import React, { useEffect, useState, lazy, Suspense, createContext } from 'react';
import PropTypes from 'prop-types';
import { Navigate, Route, Routes, useLocation } from 'react-router-dom';
-import { checkEdgePresence, getRhelSystems, getCveListByAccount } from '../Helpers/APIHelper';
import { PATHS } from '../Helpers/constants';
import { intl } from './IntlProvider';
import messages from '../Messages';
@@ -10,7 +9,7 @@ import ErrorState from '@redhat-cloud-services/frontend-components/ErrorState';
import { useChrome } from '@redhat-cloud-services/frontend-components/useChrome';
import useFeatureFlag from './useFeatureFlag';
import { NotAuthorized } from '@redhat-cloud-services/frontend-components/NotAuthorized';
-import { useNotification } from '../Helpers/Hooks';
+import { useAccountStats, useNotification } from '../Helpers/Hooks';
import PageLoading from '../Components/PresentationalComponents/Snippets/PageLoading';
const SystemsPage = lazy(() =>
@@ -54,57 +53,20 @@ export const checkForAccountSystems = (isEdgeParityEnabled, hasEdgeDevices, hasC
return isEdgeParityEnabled && (hasEdgeDevices || hasConventionalSystems) || hasConventionalSystems;
};
-export const InsightsElement = ({ element: Element, title, globalFilterEnabled, ...elementProps }) => {
+export const InsightsElement = ({ element: Element, title, globalFilterEnabled, ...elementProps }) => {
let location = useLocation();
const [isLoading, setLoading] = useState(true);
- const [hasConventionalSystems, setHasConventionalSystems] = useState(true);
- const [hasEdgeDevices, setHasEdgeDevices] = useState(true);
- const [hasAccess, setHasAccess] = useState(true);
- const [includesCvesWithoutErrata, setIncludesCvesWithoutErrata] = useState();
- const [isAdvisoryAvailable, setAdvisoryAvailable] = useState();
- const [addNotification] = useNotification();
const isEdgeParityEnabled = useFeatureFlag('vulnerability.edge_parity');
+ const [addNotification] = useNotification();
const chrome = useChrome();
- useEffect(() => {
- const fetchData = async () => {
- try {
- const rhelSystems = await getRhelSystems();
- if (isEdgeParityEnabled) {
- //if there is at least 1 edge device in the account level, not only in vulnerability
- const edgeDevicePresent = await checkEdgePresence();
- setHasEdgeDevices(edgeDevicePresent);
- }
-
- const { meta:
- {
- cves_without_errata: cvesWithoutErrata, advisory_available: advisoryAvailable
- } = {}
- } = await getCveListByAccount({ limit: 1 });
-
- setHasConventionalSystems(rhelSystems);
- setIncludesCvesWithoutErrata(cvesWithoutErrata);
- setAdvisoryAvailable(advisoryAvailable);
- setLoading(false);
- } catch (error) {
- if (error.status === '403') {
- setHasAccess(false);
- }
- else {
- addNotification({
- variant: 'danger',
- autoDismiss: false,
- msg: 'Failed to fetch systems',
- description: error.detail
- });
- }
-
- setLoading(false);
- }
- };
-
- fetchData();
- }, []);
+ const {
+ hasEdgeDevices,
+ hasConventionalSystems,
+ includesCvesWithoutErrata,
+ isAdvisoryAvailable,
+ hasAccess
+ } = useAccountStats(isEdgeParityEnabled, setLoading, addNotification);
const subPath = location.pathname && location.pathname.split('/')[4];
@@ -112,6 +74,7 @@ export const InsightsElement = ({ element: Element, title, globalFilterEnabled,
chrome.updateDocumentTitle(
`${subPath ? `${subPath} - ` : ''} ${title} - ${intl.formatMessage(messages.pageTitleSuffix)}`
);
+
}, [chrome, intl, subPath]);
useEffect(() => {
@@ -161,7 +124,8 @@ export const InsightsElement = ({ element: Element, title, globalFilterEnabled,
InsightsElement.propTypes = {
element: PropTypes.func,
title: PropTypes.string,
- globalFilterEnabled: PropTypes.bool
+ globalFilterEnabled: PropTypes.bool,
+ changeTitle: PropTypes.bool
};
export const VulnerabilityRoutes = () => {
diff --git a/src/index.js b/src/index.js
index fc1e6f227..90df19bc2 100644
--- a/src/index.js
+++ b/src/index.js
@@ -6,9 +6,11 @@ import { Provider } from 'react-redux';
import { useRbac } from './Helpers/Hooks';
import { PERMISSIONS } from './Helpers/constants';
import PageLoading from './Components/PresentationalComponents/Snippets/PageLoading';
+import { AccountStatContextWrapper } from './Utilities/AccountStatContextWrapper';
const WrappedSystemCves = ({ getRegistry, ...props }) => {
const [Wrapper, setWrapper] = useState();
+ const [isLoading, setLoading] = useState(true);
const [[canExport, canEditPairStatus]] = useRbac([PERMISSIONS.basicReporting, PERMISSIONS.setPairStatus]);
@@ -18,12 +20,23 @@ const WrappedSystemCves = ({ getRegistry, ...props }) => {
}
setWrapper(() => getRegistry ? Provider : Fragment);
+ setLoading(false);
}, []);
+ if (isLoading) {
+ return ;
+ }
+
return (
Wrapper ?
-
+
+
+
:
);