Skip to content

Commit

Permalink
Add seperate provider for context and pass as childern
Browse files Browse the repository at this point in the history
red-hat-storage#672
Signed-off-by: Timothy Asir Jeyasingh <[email protected]>
  • Loading branch information
TimothyAsirJeyasing committed Jun 20, 2024
1 parent f87daa4 commit 8717610
Show file tree
Hide file tree
Showing 2 changed files with 174 additions and 125 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -71,14 +71,22 @@ const aggregateAppsMap = (
return acc;
}, {});

const MonitoringDashboard: React.FC = () => {
const CSVStatusesProvider: React.FC = ({ children }) => {
const [csvData, csvError, csvLoading] = useCustomPrometheusPoll({
endpoint: 'api/v1/query' as any,
query: STATUS_QUERIES[StorageDashboard.CSV_STATUS_ALL_WHITELISTED],
basePath: ACM_ENDPOINT,
cluster: HUB_CLUSTER_NAME,
});

return (
<CSVStatusesContext.Provider value={{ csvData, csvError, csvLoading }}>
{children}
</CSVStatusesContext.Provider>
);
};

const DRResourcesProvider: React.FC = ({ children }) => {
const [managedClusters, managedClusterLoaded, managedClusterLoadError] =
useK8sWatchResource<ACMManagedClusterKind[]>(
getManagedClusterResourceObj()
Expand Down Expand Up @@ -122,17 +130,21 @@ const MonitoringDashboard: React.FC = () => {
loadError,
};

// ToDo(Sanjal): combime multiple Context together to make it scalable
// refer: https://javascript.plainenglish.io/how-to-combine-context-providers-for-cleaner-react-code-9ed24f20225e
return (
<CSVStatusesContext.Provider value={{ csvData, csvError, csvLoading }}>
<DRResourcesContext.Provider value={dRResourcesContext}>
<UpperSection />
</DRResourcesContext.Provider>
</CSVStatusesContext.Provider>
<DRResourcesContext.Provider value={dRResourcesContext}>
{children}
</DRResourcesContext.Provider>
);
};

const MonitoringDashboard: React.FC = () => (
<CSVStatusesProvider>
<DRResourcesProvider>
<UpperSection />
</DRResourcesProvider>
</CSVStatusesProvider>
);

const DRDashboard: React.FC = () => {
const isMonitoringEnabled = useFlag(ACM_OBSERVABILITY_FLAG);

Expand Down
271 changes: 154 additions & 117 deletions packages/odf/components/topology/Topology.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@ import {
createNode,
defaultLayoutFactory,
stylesComponentFactory,
TopologyViewLevel,
} from '@odf/shared/topology';
import {
TopologyDataContext,
TopologySearchContext,
TopologyViewLevel,
} from '@odf/shared/topology';
import {
ClusterServiceVersionKind,
Expand Down Expand Up @@ -99,6 +101,149 @@ type SideBarProps = {
isExpanded: boolean;
};

const TopologyDataProvider: React.FC<{
children: React.ReactNode;
visualizationLevel: TopologyViewLevel;
activeNode: string;
setActiveNode: React.Dispatch<React.SetStateAction<string>>;
}> = ({ children, visualizationLevel, activeNode, setActiveNode }) => {
const [nodes, nodesLoaded, nodesError] =
useK8sWatchResource<NodeKind[]>(nodeResource);
const { odfNamespace, isODFNsLoaded, odfNsLoadError } =
useODFNamespaceSelector();
const [storageClusters, storageClustersLoaded, storageClustersError] =
useK8sWatchResource<StorageClusterKind[]>(storageClusterResource);
const [selectedElement, setSelectedElement] =
React.useState<GraphElement | null>(null);

const storageCluster = getStorageClusterInNs(storageClusters, odfNamespace);
const storageLabel = cephStorageLabel(odfNamespace);
const odfNodes = nodes.filter((node) =>
_.has(node.metadata.labels, storageLabel)
);

const [deployments, deploymentsLoaded, deploymentsError] =
useSafeK8sWatchResource<DeploymentKind[]>(odfDeploymentsResource);

const [pods, podsLoaded, podsError] =
useSafeK8sWatchResource<PodKind[]>(odfPodsResource);

const [statefulSets, statefulSetLoaded, statefulSetError] =
useSafeK8sWatchResource<K8sResourceCommon[]>(odfStatefulSetResource);

const [replicaSets, replicaSetsLoaded, replicaSetsError] =
useSafeK8sWatchResource<K8sResourceCommon[]>(odfReplicaSetResource);

const [daemonSets, daemonSetsLoaded, daemonSetError] =
useSafeK8sWatchResource<K8sResourceCommon[]>(odfDaemonSetResource);

const memoizedNodes = useDeepCompareMemoize(odfNodes, true);
const memoizedDeployments = useDeepCompareMemoize(deployments, true);
const memoizedPods = useDeepCompareMemoize(pods, true);
const memoizedStatefulSets = useDeepCompareMemoize(statefulSets, true);
const memoizedReplicaSets = useDeepCompareMemoize(replicaSets, true);
const memoizedDaemonSets = useDeepCompareMemoize(daemonSets, true);
const zones = memoizedNodes.map(getTopologyDomain);

const nodeDeploymentMap = React.useMemo(
() =>
generateNodeDeploymentsMap(
memoizedNodes,
memoizedPods,
memoizedDeployments,
...memoizedReplicaSets,
...memoizedDaemonSets,
...memoizedStatefulSets,
...memoizedDeployments
),
[
memoizedDaemonSets,
memoizedDeployments,
memoizedNodes,
memoizedPods,
memoizedReplicaSets,
memoizedStatefulSets,
]
);

const value = {
nodes: memoizedNodes,
storageCluster,
zones: zones,
deployments: memoizedDeployments,
visualizationLevel: visualizationLevel,
activeNode,
setActiveNode,
nodeDeploymentMap,
selectedElement,
setSelectedElement,
};

const Error = ({ error }) => <>{error}</>;

const loading =
!nodesLoaded ||
!storageClustersLoaded ||
!deploymentsLoaded ||
!podsLoaded ||
!statefulSetLoaded ||
!replicaSetsLoaded ||
!daemonSetsLoaded ||
!isODFNsLoaded;

const error =
deploymentsError ||
podsError ||
statefulSetError ||
replicaSetsError ||
daemonSetError;

return (
<>
{loading || error ? (
<HandleErrorAndLoading
loading={loading}
error={
storageClustersError ||
nodesError ||
deploymentsError ||
podsError ||
replicaSetsError ||
daemonSetError ||
statefulSetError ||
odfNsLoadError
}
ErrorMessage={Error}
/>
) : (
<TopologyDataContext.Provider value={value}>
{children}
</TopologyDataContext.Provider>
)}
</>
);
};

const TopologySearchProvider: React.FC<{ children: React.ReactNode }> = ({
children,
}) => {
const [activeItemsUID, setActiveItemsUID] = React.useState<string[]>([]);
const [activeItem, setActiveItem] = React.useState<string>('');

const value = {
activeItemsUID,
setActiveItemsUID,
activeItem,
setActiveItem,
};

return (
<TopologySearchContext.Provider value={value}>
{children}
</TopologySearchContext.Provider>
);
};

const Sidebar: React.FC<SideBarProps> = ({ onClose, isExpanded }) => {
const { selectedElement: element } = React.useContext(TopologyDataContext);
const data = element?.getData();
Expand Down Expand Up @@ -458,81 +603,11 @@ const TopologyViewComponent: React.FC = () => {
);
};

const Error = ({ error }) => <>{error}</>;

const Topology: React.FC = () => {
const { odfNamespace, isODFNsLoaded, odfNsLoadError } =
useODFNamespaceSelector();

const [controller, setController] = React.useState<Visualization>(null);
const [visualizationLevel, setVisualizationLevel] =
React.useState<TopologyViewLevel>(TopologyViewLevel.NODES);
const [activeItemsUID, setActiveItemsUID] = React.useState<string[]>([]);
const [activeItem, setActiveItem] = React.useState<string>('');
const [activeNode, setActiveNode] = React.useState('');
const [selectedElement, setSelectedElement] =
React.useState<GraphElement>(null);

const [nodes, nodesLoaded, nodesError] =
useK8sWatchResource<NodeKind[]>(nodeResource);

const [storageClusters, storageClustersLoaded, storageClustersError] =
useK8sWatchResource<StorageClusterKind[]>(storageClusterResource);

const [deployments, deploymentsLoaded, deploymentsError] =
useSafeK8sWatchResource<DeploymentKind[]>(odfDeploymentsResource);

const [pods, podsLoaded, podsError] =
useSafeK8sWatchResource<PodKind[]>(odfPodsResource);

const [statefulSets, statefulSetLoaded, statefulSetError] =
useSafeK8sWatchResource<K8sResourceCommon[]>(odfStatefulSetResource);

const [replicaSets, replicaSetsLoaded, replicaSetsError] =
useSafeK8sWatchResource<K8sResourceCommon[]>(odfReplicaSetResource);

const [daemonSets, daemonSetsLoaded, daemonSetError] =
useSafeK8sWatchResource<K8sResourceCommon[]>(odfDaemonSetResource);

// ToDo (epic 4422): This will work as Internal mode cluster will only be created in ODF install namespace.
// Still, make this generic so that this works even if it gets created in a different namespace.
const storageCluster: StorageClusterKind = getStorageClusterInNs(
storageClusters,
odfNamespace
);

const storageLabel = cephStorageLabel(odfNamespace);
const odfNodes = nodes.filter((node) =>
_.has(node.metadata.labels, storageLabel)
);

const memoizedNodes = useDeepCompareMemoize(odfNodes, true);
const memoizedDeployments = useDeepCompareMemoize(deployments, true);
const memoizedPods = useDeepCompareMemoize(pods, true);
const memoizedStatefulSets = useDeepCompareMemoize(statefulSets, true);
const memoizedReplicaSets = useDeepCompareMemoize(replicaSets, true);
const memoizedDaemonSets = useDeepCompareMemoize(daemonSets, true);

const nodeDeploymentMap = React.useMemo(
() =>
generateNodeDeploymentsMap(
memoizedNodes,
memoizedPods,
memoizedDeployments,
...memoizedReplicaSets,
...memoizedDaemonSets,
...memoizedStatefulSets,
...memoizedDeployments
),
[
memoizedDaemonSets,
memoizedDeployments,
memoizedNodes,
memoizedPods,
memoizedReplicaSets,
memoizedStatefulSets,
]
);

const onStepInto = (args) => {
const nodeName = args.label;
Expand All @@ -559,59 +634,21 @@ const Topology: React.FC = () => {
};
}, []);

const loading =
!nodesLoaded ||
!storageClustersLoaded ||
!deploymentsLoaded ||
!podsLoaded ||
!statefulSetLoaded ||
!replicaSetsLoaded ||
!daemonSetsLoaded ||
!isODFNsLoaded;

const zones = memoizedNodes.map(getTopologyDomain);

return (
<TopologyDataContext.Provider
value={{
nodes: memoizedNodes,
storageCluster: storageCluster,
zones,
deployments: memoizedDeployments,
visualizationLevel: visualizationLevel,
activeNode,
setActiveNode,
nodeDeploymentMap,
selectedElement,
setSelectedElement: setSelectedElement as any,
}}
<TopologyDataProvider
visualizationLevel={visualizationLevel}
activeNode={activeNode}
setActiveNode={setActiveNode}
>
<TopologySearchContext.Provider
value={{ activeItemsUID, setActiveItemsUID, activeItem, setActiveItem }}
>
<TopologySearchProvider>
<VisualizationProvider controller={controller}>
<div className="odf__topology-view" id="odf-topology">
<TopologyTopBar />
<HandleErrorAndLoading
loading={loading}
error={
storageClustersError ||
nodesError ||
deploymentsError ||
podsError ||
replicaSetsError ||
daemonSetError ||
statefulSetError ||
odfNsLoadError
}
ErrorMessage={Error}
>
<TopologyViewComponent />
</HandleErrorAndLoading>
<TopologyViewComponent />
</div>
</VisualizationProvider>
</TopologySearchContext.Provider>
</TopologyDataContext.Provider>
</TopologySearchProvider>
</TopologyDataProvider>
);
};

Expand Down

0 comments on commit 8717610

Please sign in to comment.