Skip to content
Snippets Groups Projects
Commit 914a3897 authored by Mohammad Torkashvand's avatar Mohammad Torkashvand
Browse files

Refactor data fetching and state management in MapsPage

- Move data fetching logic from NetworkMap to MapsPage
- Handle loading and error states in MapsPage
- Remove loading and error handling from NetworkMap
- Ensure separation of concerns between data fetching and presentation

This refactor simplifies NetworkMap by focusing it solely on rendering the network map, while MapsPage handles data fetching, session management, and error handling.
parent 98b9232a
No related branches found
No related tags found
1 merge request!30Refactor data fetching and state management in MapsPage
Pipeline #87044 passed
import { NetworkTopologyData } from '@/types/types';
import {
EuiToolTip,
EuiSelect,
EuiLoadingSpinner,
EuiPanel,
EuiFormRow,
} from '@elastic/eui';
import { EuiToolTip, EuiSelect, EuiPanel, EuiFormRow } from '@elastic/eui';
import cytoscape, { ElementDefinition, Core } from 'cytoscape';
import fcose from 'cytoscape-fcose';
import React, { useEffect, useState, useRef } from 'react';
......@@ -26,7 +20,6 @@ interface FcoseLayoutOptions {
const NetworkMap: React.FC<NetworkMapProps> = ({ data }) => {
const [elements, setElements] = useState<ElementDefinition[]>([]);
const [labelType, setLabelType] = useState('iptrunkIsisMetric');
const [loading, setLoading] = useState(true);
const [tooltipContent, setTooltipContent] = useState<JSX.Element | null>(
null,
);
......@@ -40,7 +33,6 @@ const NetworkMap: React.FC<NetworkMapProps> = ({ data }) => {
if (data) {
const transformedElements = transformDataToElements(data);
setElements(transformedElements);
setLoading(false);
}
}, [data]);
......@@ -295,11 +287,7 @@ const NetworkMap: React.FC<NetworkMapProps> = ({ data }) => {
return (
<EuiPanel>
{loading ? (
<EuiLoadingSpinner size="xl" />
) : (
<div id="container" style={{ height: '80vh', marginTop: '20px' }}></div>
)}
<div id="container" style={{ height: '80vh', marginTop: '20px' }}></div>
{tooltipContent && tooltipPosition && (
<div
style={{
......
......@@ -3,6 +3,7 @@ import React, { createContext, useContext, ReactNode } from 'react';
export interface GsoConfig {
opaPublicBundleUrl: string;
oidcClientId: string;
networkTopologyApiUrl: string;
}
const GsoConfigContext = createContext<GsoConfig | undefined>(undefined);
......
......@@ -3,6 +3,7 @@ import { NextApiRequest, NextApiResponse } from 'next';
interface RuntimeConfig {
opaPublicBundleUrl: string;
oidcClientId: string;
networkTopologyApiUrl: string;
}
export default async function handler(
......@@ -12,6 +13,7 @@ export default async function handler(
const config: RuntimeConfig = {
opaPublicBundleUrl: process.env.OPA_PUBLIC_BUNDLE_URL || '',
oidcClientId: process.env.NEXTAUTH_CLIENT_ID || '',
networkTopologyApiUrl: process.env.NETWORK_TOPOLOGY_API_URL || '',
};
res.status(200).json(config);
......
import NetworkMap from '@/components/NetworkMap/NetworkMap';
import { useGsoConfig } from '@/contexts/GsoConfigContext';
import { GSOPolicyResource } from '@/types/policyResources';
import { NetworkTopologyData } from '@/types/types';
import { WfoPolicyRenderPageFallback } from '@orchestrator-ui/orchestrator-ui-components';
import { EuiLoadingSpinner, EuiText } from '@elastic/eui';
import {
useWfoSession,
WfoPolicyRenderPageFallback,
} from '@orchestrator-ui/orchestrator-ui-components';
import axios from 'axios';
import { NextPage, GetServerSideProps } from 'next';
import React from 'react';
import React, { useEffect, useState } from 'react';
interface MapsProps {
networkTopologyData: NetworkTopologyData;
}
const MapsPage: React.FC = () => {
const [networkTopologyData, setNetworkTopologyData] =
useState<NetworkTopologyData | null>(null);
const [loading, setLoading] = useState<boolean>(true);
const [error, setError] = useState<boolean>(false);
const TIMEOUT = 5000;
const config = useGsoConfig();
const { session } = useWfoSession();
const AXIOS_TIMEOUT = 10000; // 10 seconds
useEffect(() => {
const fetchData = async () => {
try {
const requestHeaders = {
Authorization: session ? `Bearer ${session.accessToken}` : '',
};
const response = await axios.get<NetworkTopologyData>(
config.networkTopologyApiUrl!,
{
timeout: TIMEOUT,
headers: requestHeaders,
},
);
setNetworkTopologyData(response.data);
setLoading(false);
} catch (error) {
console.error('Failed to fetch data', error);
setError(true);
setLoading(false);
}
};
if (session) {
fetchData();
} else {
setLoading(false);
setError(true);
}
}, [session]);
const MapsPage: NextPage<MapsProps> = ({ networkTopologyData }) => {
return (
<WfoPolicyRenderPageFallback resource={GSOPolicyResource.NAVIGATION_MAPS}>
<NetworkMap data={networkTopologyData} />
{loading ? (
<EuiLoadingSpinner size="xl" />
) : error ? (
<EuiText color="danger">
Failed to load data. Please try again later.
</EuiText>
) : (
<NetworkMap data={networkTopologyData} />
)}
</WfoPolicyRenderPageFallback>
);
};
export const getServerSideProps: GetServerSideProps = async () => {
try {
const response = await axios.get(process.env.NETWORK_TOPOLOGY_API_URL!, {
timeout: AXIOS_TIMEOUT,
});
const networkTopologyData: NetworkTopologyData = response.data;
return {
props: {
networkTopologyData,
},
};
} catch (error) {
console.error('Failed to fetch data', error);
return {
props: {
networkTopologyData: null,
},
};
}
};
export default MapsPage;
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment