From 18c7a3e245a41acfa5abc64db32e1ebda6bd8d42 Mon Sep 17 00:00:00 2001 From: Michal Gold Date: Tue, 21 Nov 2023 17:18:24 +0200 Subject: [PATCH] feat(THEEDGE-3693): Implement edge groups exposition (#2086) Implements https://issues.redhat.com/browse/THEEDGE-3693. this fixes story add support for important customer that will navigate to group screen and show edge group instead of inventory group. this pr expose Groups component from edge and check if user should see inventory or edge groups --- src/Routes.js | 7 +-- src/Utilities/hooks/useEdgeGroups.js | 34 ++++++++++++ src/api/api.js | 8 +++ src/components/InventoryGroups/EdgeGroups.js | 26 +++++++++ src/routes/InventoryOrEdgeComponent.js | 56 ++++++++++++++++++++ 5 files changed, 128 insertions(+), 3 deletions(-) create mode 100644 src/Utilities/hooks/useEdgeGroups.js create mode 100644 src/components/InventoryGroups/EdgeGroups.js create mode 100644 src/routes/InventoryOrEdgeComponent.js diff --git a/src/Routes.js b/src/Routes.js index 88a024200..46247d42d 100644 --- a/src/Routes.js +++ b/src/Routes.js @@ -16,10 +16,11 @@ import AsynComponent from '@redhat-cloud-services/frontend-components/AsyncCompo import ErrorState from '@redhat-cloud-services/frontend-components/ErrorState'; import { inventoryHasEdgeSystems } from './Utilities/edge'; import { inventoryHasConventionalSystems } from './Utilities/conventional'; - +const InventoryOrEdgeView = lazy(() => + import('./routes/InventoryOrEdgeComponent') +); const InventoryTable = lazy(() => import('./routes/InventoryTable')); const InventoryDetail = lazy(() => import('./routes/InventoryDetail')); -const InventoryGroups = lazy(() => import('./routes/InventoryGroups')); const InventoryHostStaleness = lazy(() => import('./routes/InventoryHostStaleness') ); @@ -77,7 +78,7 @@ export const Routes = () => { { path: '/:inventoryId/:modalId', element: }, { path: '/groups', - element: groupsEnabled ? : , + element: groupsEnabled ? : , }, { path: '/groups/:groupId', diff --git a/src/Utilities/hooks/useEdgeGroups.js b/src/Utilities/hooks/useEdgeGroups.js new file mode 100644 index 000000000..098887c6d --- /dev/null +++ b/src/Utilities/hooks/useEdgeGroups.js @@ -0,0 +1,34 @@ +import { useEffect, useState } from 'react'; +import useFeatureFlag from '../useFeatureFlag'; +import { fetchEdgeEnforceGroups } from '../../api'; + +const useEdgeGroups = () => { + const [data, setData] = useState(false); + const [isLoading, setIsLoading] = useState(false); + + const edgeParityInventoryGroupsEnabled = useFeatureFlag( + 'edgeParity.inventory-groups-enabled' + ); + + useEffect(() => { + const fetchData = async () => { + setIsLoading(true); + try { + if (edgeParityInventoryGroupsEnabled) { + const response = await fetchEdgeEnforceGroups(); + const enforceEdgeGroups = response?.enforce_edge_groups; + setData(enforceEdgeGroups); + } + } catch (error) { + console.error(error); + } finally { + setIsLoading(false); + } + }; + + fetchData(); + }, []); + return [data, isLoading]; +}; + +export default useEdgeGroups; diff --git a/src/api/api.js b/src/api/api.js index bd5d86bc8..310b12848 100644 --- a/src/api/api.js +++ b/src/api/api.js @@ -399,3 +399,11 @@ export const fetchEdgeSystem = () => { console.log(err); } }; + +export const fetchEdgeEnforceGroups = () => { + try { + return instance.get(`${EDGE_API_BASE}/device-groups/enforce-edge-groups`); + } catch (err) { + console.error(err); + } +}; diff --git a/src/components/InventoryGroups/EdgeGroups.js b/src/components/InventoryGroups/EdgeGroups.js new file mode 100644 index 000000000..f765ba624 --- /dev/null +++ b/src/components/InventoryGroups/EdgeGroups.js @@ -0,0 +1,26 @@ +import React from 'react'; +import AsyncComponent from '@redhat-cloud-services/frontend-components/AsyncComponent'; +import ErrorState from '@redhat-cloud-services/frontend-components/ErrorState'; +import { resolveRelPath } from '../../Utilities/path'; +import { getNotificationProp } from '../../Utilities/edge'; +import { useLocation, useNavigate } from 'react-router-dom'; +import { useDispatch } from 'react-redux'; + +const EdgeGroupsView = (props) => { + const dispatch = useDispatch(); + const notificationProp = getNotificationProp(dispatch); + return ( + } + navigateProp={useNavigate} + locationProp={useLocation} + notificationProp={notificationProp} + pathPrefix={resolveRelPath('')} + {...props} + /> + ); +}; + +export default EdgeGroupsView; diff --git a/src/routes/InventoryOrEdgeComponent.js b/src/routes/InventoryOrEdgeComponent.js new file mode 100644 index 000000000..2916a3d69 --- /dev/null +++ b/src/routes/InventoryOrEdgeComponent.js @@ -0,0 +1,56 @@ +import React, { useEffect, useState } from 'react'; +import EdgeGroupsView from '../components/InventoryGroups/EdgeGroups'; +import InventoryGroups from '../components/InventoryGroups/InventoryGroups'; +import { inventoryHasConventionalSystems } from '../Utilities/conventional'; +import { inventoryHasEdgeSystems } from '../Utilities/edge'; +import useEdgeGroups from '../Utilities/hooks/useEdgeGroups'; +import useFeatureFlag from '../Utilities/useFeatureFlag'; +import PropTypes from 'prop-types'; +import { Bullseye, Spinner } from '@patternfly/react-core'; + +const InventoryOrEdgeView = () => { + const [enforceEdgeGroups, isLoading] = useEdgeGroups(); + const [hasConventionalSystems, setHasConventionalSystems] = useState(true); + const [hasEdgeDevices, setHasEdgeDevices] = useState(true); + const edgeParityInventoryListEnabled = useFeatureFlag( + 'edgeParity.inventory-list' + ); + + useEffect(() => { + try { + (async () => { + const hasConventionalSystems = await inventoryHasConventionalSystems(); + if (edgeParityInventoryListEnabled) { + const hasEdgeSystems = await inventoryHasEdgeSystems(); + setHasConventionalSystems(hasConventionalSystems); + setHasEdgeDevices(hasEdgeSystems); + } + })(); + } catch (e) { + console.error(e); + } + }, []); + + const ViewComponent = enforceEdgeGroups ? EdgeGroupsView : InventoryGroups; + if (!isLoading) { + return ( + + ); + } else { + return ( + + + + ); + } +}; + +InventoryOrEdgeView.prototype = { + enforceEdgeGroups: PropTypes.bool, + isLoading: PropTypes.bool, +}; + +export default InventoryOrEdgeView;