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

added maps to the menues

parent 248e237d
Branches
Tags
1 merge request!28added maps to the menu
Pipeline #87028 passed
......@@ -17,8 +17,12 @@ NEXTAUTH_WELL_KNOWN_OVERRIDE="http://localhost:8085/auth/.well-known/openid-conf
NEXTAUTH_AUTHORIZATION_SCOPE_OVERRIDE="openid profile"
NEXTAUTH_URL=http://localhost:3000/api/auth
# OPA Settings
OPA_PUBLIC_BUNDLE_URL=http://localhost:8181/v1/data/opa/public-bundle
#Maps Settings
NETWORK_TOPOLOGY_API_URL="https://orchestrator.uat.gap.geant.org/api/v1/networks/topology"
# docker-compose variables
KEYCLOAK_ADMIN=admin
KEYCLOAK_ADMIN_PASSWORD=admin
......
import {
EuiToolTip,
EuiSelect,
EuiLoadingSpinner,
EuiPanel,
EuiFormRow,
} from '@elastic/eui';
import cytoscape, { ElementDefinition, Core } from 'cytoscape';
import fcose from 'cytoscape-fcose';
import React, { useEffect, useState, useRef } from 'react';
cytoscape.use(fcose);
interface IptrunkSideNode {
subscription_instance_id: string;
router_fqdn: string;
router_access_via_ts: boolean;
router_lo_ipv4_address: string;
router_lo_ipv6_address: string;
router_lo_iso_address: string;
router_role: string;
vendor: string;
router_site: {
site_internal_id: string;
site_name: string;
site_city: string;
site_country: string;
site_latitude: number;
site_longitude: number;
};
}
interface Iptrunk {
subscription_instance_id: string;
iptrunk_isis_metric: string;
iptrunk_capacity: string;
iptrunk_type: string;
iptrunk_ipv4_network: string;
iptrunk_ipv6_network: string;
iptrunk_sides: Array<{ iptrunk_side_node: IptrunkSideNode }>;
}
export interface NetworkTopologyData {
iptrunks: Array<{ iptrunk: Iptrunk; insync: boolean }>;
}
export interface NetworkMapProps {
data: NetworkTopologyData | null;
}
interface FcoseLayoutOptions {
name: 'fcose';
quality: string;
nodeRepulsion: (node: cytoscape.NodeSingular) => number;
idealEdgeLength: (edge: cytoscape.EdgeSingular) => number;
}
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,
);
const [tooltipPosition, setTooltipPosition] = useState<{
x: number;
y: number;
} | null>(null);
const cyRef = useRef<Core | null>(null);
useEffect(() => {
if (data) {
const transformedElements = transformDataToElements(data);
setElements(transformedElements);
setLoading(false);
}
}, [data]);
useEffect(() => {
if (elements.length > 0) {
const layoutOptions: FcoseLayoutOptions = {
name: 'fcose',
quality: 'proof',
nodeRepulsion: () => 10000,
idealEdgeLength: () => 300,
};
const cy: Core = cytoscape({
container: document.getElementById('container'),
elements,
boxSelectionEnabled: false,
autounselectify: true,
minZoom: 0.25,
maxZoom: 4,
style: [
{
selector: 'node',
style: {
label: 'data(label)',
'background-color': '#95a5a6',
'font-size': '12px',
color: 'black',
},
},
{
selector: '.router',
style: {
width: 1,
height: 1,
'background-fit': 'contain',
'background-position-x': '50%',
'background-position-y': '50%',
'background-clip': 'none',
},
},
{
selector: '.nokia',
style: {
'background-image': 'url("/images/nokia_icon.png")',
},
},
{
selector: '.juniper',
style: {
'background-image': 'url("/images/juniper_icon.png")',
},
},
{
selector: 'edge',
style: {
width: 3,
'line-color': '#3498db',
'target-arrow-color': '#3498db',
'curve-style': 'bezier',
label: 'data(label)',
'text-rotation': 'autorotate',
'font-size': '10px',
color: '#2c3e50',
'text-outline-color': '#ecf0f1',
'text-outline-width': 3,
},
},
{
selector: 'edge[insync="true"]',
style: {
'line-color': '#2ecc71',
},
},
{
selector: 'edge[insync="false"]',
style: {
'line-color': '#e74c3c',
},
},
{
selector: '.site',
style: {
'background-opacity': 0.1,
'text-valign': 'top',
'text-halign': 'left',
'font-weight': 'bold',
'font-size': '14px',
'border-color': '#2980b9',
'border-width': 1,
},
},
],
layout: layoutOptions,
});
cyRef.current = cy;
cy.on('zoom', function () {
updateElementStyles(cy);
});
cy.on('mouseover', 'node', function (event) {
const node = event.target;
const router = node.data('self');
if (router) {
const nodeInfo = (
<div style={{ whiteSpace: 'nowrap' }}>
<strong>subscription_id:</strong>{' '}
{router.subscription_instance_id || 'N/A'} <br />
<strong>router_fqdn:</strong> {router.router_fqdn || 'N/A'} <br />
<strong>router_access_via_ts:</strong>{' '}
{router.router_access_via_ts ? 'true' : 'false'} <br />
<strong>router_lo_ipv4_address:</strong>{' '}
{router.router_lo_ipv4_address || 'N/A'} <br />
<strong>router_lo_ipv6_address:</strong>{' '}
{router.router_lo_ipv6_address || 'N/A'} <br />
<strong>router_lo_iso_address:</strong>{' '}
{router.router_lo_iso_address || 'N/A'} <br />
<strong>router_role:</strong> {router.router_role || 'N/A'} <br />
<strong>vendor:</strong> {router.vendor || 'N/A'} <br />
</div>
);
setTooltipContent(nodeInfo);
setTooltipPosition({
x: event.renderedPosition.x,
y: event.renderedPosition.y,
});
}
});
cy.on('mouseout', 'node', function () {
setTooltipContent(null);
setTooltipPosition(null);
});
}
}, [elements]);
const handleLabelChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
const selectedValue = e.target.value;
setLabelType(selectedValue);
const cy = cyRef.current;
if (cy) {
cy.edges().forEach((edge) => {
const iptrunk = edge.data('self');
let label = '';
switch (selectedValue) {
case 'iptrunkCapacity':
label = iptrunk.iptrunk_capacity;
break;
case 'iptrunkIsisMetric':
label = iptrunk.iptrunk_isis_metric;
break;
case 'iptrunkType':
label = iptrunk.iptrunk_type;
break;
case 'iptrunkIPV4Network':
label = iptrunk.iptrunk_ipv4_network;
break;
case 'iptrunkIPV6Network':
label = iptrunk.iptrunk_ipv6_network;
break;
}
edge.data('label', label);
});
}
};
const transformDataToElements = (
data: NetworkTopologyData,
): ElementDefinition[] => {
const elements: ElementDefinition[] = [];
const sites = new Map<string, boolean>();
data.iptrunks.forEach((trunk) => {
trunk.iptrunk.iptrunk_sides.forEach((side) => {
const siteData = side.iptrunk_side_node.router_site;
const siteId = `site-${siteData.site_internal_id}`;
if (!sites.has(siteId)) {
const { x, y } = latLongToXY(
siteData.site_latitude,
siteData.site_longitude,
);
elements.push({
data: {
id: siteId,
label: `${siteData.site_name} (${siteData.site_city}, ${siteData.site_country})`,
},
position: { x, y },
classes: ['site'],
});
sites.set(siteId, true);
}
elements.push({
data: {
id: side.iptrunk_side_node.subscription_instance_id,
parent: siteId,
label: side.iptrunk_side_node.router_fqdn,
self: side.iptrunk_side_node,
},
classes: ['router', side.iptrunk_side_node.vendor.toLowerCase()],
});
});
elements.push({
data: {
id: trunk.iptrunk.subscription_instance_id,
source:
trunk.iptrunk.iptrunk_sides[0].iptrunk_side_node
.subscription_instance_id,
target:
trunk.iptrunk.iptrunk_sides[1].iptrunk_side_node
.subscription_instance_id,
label: trunk.iptrunk.iptrunk_isis_metric,
insync: trunk.insync.toString(),
self: trunk.iptrunk,
},
});
});
return elements;
};
const latLongToXY = (
latitude: number,
longitude: number,
): { x: number; y: number } => {
const x = (longitude + 180) * (1000 / 360);
const y = (90 - latitude) * (500 / 180);
return { x, y };
};
const updateElementStyles = (cy: Core) => {
const zoom = cy.zoom();
const baseNodeSize = 10;
const baseFontSize = 5;
const scaledNodeSize = baseNodeSize * zoom;
const scaledFontSize = baseFontSize * zoom;
cy.style()
.selector('node')
.style({
width: scaledNodeSize,
height: scaledNodeSize,
'font-size': scaledFontSize,
})
.update();
};
return (
<EuiPanel>
{loading ? (
<EuiLoadingSpinner size="xl" />
) : (
<div id="container" style={{ height: '80vh', marginTop: '20px' }}></div>
)}
{tooltipContent && tooltipPosition && (
<div
style={{
position: 'absolute',
left: tooltipPosition.x + 20,
top: tooltipPosition.y + 20,
pointerEvents: 'none',
zIndex: 9999,
}}
>
<EuiToolTip position="top" display="block">
<div
style={{
display: 'inline-block',
width: '450px',
backgroundColor: 'white',
border: '1px solid #ccc',
padding: '10px',
borderRadius: '5px',
zIndex: 9999,
boxShadow: '0 0 10px rgba(0,0,0,0.2)',
}}
>
{tooltipContent}
</div>
</EuiToolTip>
</div>
)}
<EuiFormRow fullWidth>
<EuiSelect
id="labelSelector"
options={[
{ value: 'iptrunkIsisMetric', text: 'Iptrunk ISIS Metric' },
{ value: 'iptrunkCapacity', text: 'Iptrunk Capacity' },
{ value: 'iptrunkType', text: 'Iptrunk Type' },
{ value: 'iptrunkIPV4Network', text: 'Iptrunk IPV4 Network' },
{ value: 'iptrunkIPV6Network', text: 'Iptrunk IPV6 Network' },
]}
value={labelType}
onChange={handleLabelChange}
/>
</EuiFormRow>
</EuiPanel>
);
};
export default NetworkMap;
......@@ -15,6 +15,9 @@
"@open-policy-agent/opa-wasm": "^1.8.1",
"@orchestrator-ui/orchestrator-ui-components": "1.20.0",
"@reduxjs/toolkit": "^2.0.1",
"axios": "^1.7.2",
"cytoscape": "^3.29.2",
"cytoscape-fcose": "^2.2.0",
"moment": "^2.29.4",
"next": "^14.0.4",
"next-auth": "^4.24.5",
......@@ -34,8 +37,10 @@
"@orchestrator-ui/jest-config": "*",
"@orchestrator-ui/tsconfig": "*",
"@testing-library/jest-dom": "^6.2.0",
"@types/cytoscape": "^3.21.2",
"@types/cytoscape-fcose": "^2.2.4",
"@types/node": "^20.10.5",
"@types/react": "^18.2.45",
"@types/react": "^18.3.3",
"@types/react-dom": "^18.2.18",
"@types/react-no-ssr": "^1.1.7",
"esbuild-jest": "^0.5.0",
......@@ -2365,6 +2370,126 @@
"node": ">= 10"
}
},
"node_modules/@next/swc-darwin-x64": {
"version": "14.2.3",
"resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.3.tgz",
"integrity": "sha512-6adp7waE6P1TYFSXpY366xwsOnEXM+y1kgRpjSRVI2CBDOcbRjsJ67Z6EgKIqWIue52d2q/Mx8g9MszARj8IEA==",
"cpu": [
"x64"
],
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@next/swc-linux-arm64-gnu": {
"version": "14.2.3",
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.3.tgz",
"integrity": "sha512-cuzCE/1G0ZSnTAHJPUT1rPgQx1w5tzSX7POXSLaS7w2nIUJUD+e25QoXD/hMfxbsT9rslEXugWypJMILBj/QsA==",
"cpu": [
"arm64"
],
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@next/swc-linux-arm64-musl": {
"version": "14.2.3",
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.3.tgz",
"integrity": "sha512-0D4/oMM2Y9Ta3nGuCcQN8jjJjmDPYpHX9OJzqk42NZGJocU2MqhBq5tWkJrUQOQY9N+In9xOdymzapM09GeiZw==",
"cpu": [
"arm64"
],
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@next/swc-linux-x64-gnu": {
"version": "14.2.3",
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.3.tgz",
"integrity": "sha512-ENPiNnBNDInBLyUU5ii8PMQh+4XLr4pG51tOp6aJ9xqFQ2iRI6IH0Ds2yJkAzNV1CfyagcyzPfROMViS2wOZ9w==",
"cpu": [
"x64"
],
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@next/swc-linux-x64-musl": {
"version": "14.2.3",
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.3.tgz",
"integrity": "sha512-BTAbq0LnCbF5MtoM7I/9UeUu/8ZBY0i8SFjUMCbPDOLv+un67e2JgyN4pmgfXBwy/I+RHu8q+k+MCkDN6P9ViQ==",
"cpu": [
"x64"
],
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@next/swc-win32-arm64-msvc": {
"version": "14.2.3",
"resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.3.tgz",
"integrity": "sha512-AEHIw/dhAMLNFJFJIJIyOFDzrzI5bAjI9J26gbO5xhAKHYTZ9Or04BesFPXiAYXDNdrwTP2dQceYA4dL1geu8A==",
"cpu": [
"arm64"
],
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@next/swc-win32-ia32-msvc": {
"version": "14.2.3",
"resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.3.tgz",
"integrity": "sha512-vga40n1q6aYb0CLrM+eEmisfKCR45ixQYXuBXxOOmmoV8sYST9k7E3US32FsY+CkkF7NtzdcebiFT4CHuMSyZw==",
"cpu": [
"ia32"
],
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@next/swc-win32-x64-msvc": {
"version": "14.2.3",
"resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.3.tgz",
"integrity": "sha512-Q1/zm43RWynxrO7lW4ehciQVj+5ePBhOK+/K2P7pLFX3JaJ/IZVC69SHidrmZSOkqz7ECIOhhy7XhAFG4JYyHA==",
"cpu": [
"x64"
],
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@nodelib/fs.scandir": {
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
......@@ -2913,6 +3038,21 @@
"@babel/types": "^7.20.7"
}
},
"node_modules/@types/cytoscape": {
"version": "3.21.2",
"resolved": "https://registry.npmjs.org/@types/cytoscape/-/cytoscape-3.21.2.tgz",
"integrity": "sha512-eadSCH9hbRV9Ej93S8wact/Oe0DuQV4qlWfST/I6k4lBu6RgqI6mVFzvppcIGzWpzZRu7iyFjFhS2qW0w7KFRA==",
"dev": true
},
"node_modules/@types/cytoscape-fcose": {
"version": "2.2.4",
"resolved": "https://registry.npmjs.org/@types/cytoscape-fcose/-/cytoscape-fcose-2.2.4.tgz",
"integrity": "sha512-QwWtnT8HI9h+DHhG5krGc1ZY0Ex+cn85MvX96ZNAjSxuXiZDnjIZW/ypVkvvubTjIY4rSdkJY1D/Nsn8NDpmAw==",
"dev": true,
"dependencies": {
"@types/cytoscape": "*"
}
},
"node_modules/@types/graceful-fs": {
"version": "4.1.9",
"resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz",
......@@ -3076,9 +3216,9 @@
"integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q=="
},
"node_modules/@types/react": {
"version": "18.3.2",
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.2.tgz",
"integrity": "sha512-Btgg89dAnqD4vV7R3hlwOxgqobUQKgx3MmrQRi0yYbs/P0ym8XozIAlkqVilPqHQwXs4e9Tf63rrCgl58BcO4w==",
"version": "18.3.3",
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.3.tgz",
"integrity": "sha512-hti/R0pS0q1/xx+TsI73XIqk26eBsISZ2R0wUijXIngRK9R/e7Xw/cXVxQK7R5JjW+SV4zGcn5hXjudkN/pLIw==",
"dependencies": {
"@types/prop-types": "*",
"csstype": "^3.0.2"
......@@ -3794,9 +3934,9 @@
}
},
"node_modules/axios": {
"version": "1.6.8",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.6.8.tgz",
"integrity": "sha512-v/ZHtJDU39mDpyBoFVkETcd/uNdxrWRrg3bKpOKzXFA6Bvqopts6ALSMU3y6ijYxbw2B+wPrIv46egTzJXCLGQ==",
"version": "1.7.2",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.7.2.tgz",
"integrity": "sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==",
"dependencies": {
"follow-redirects": "^1.15.6",
"form-data": "^4.0.0",
......@@ -4481,6 +4621,14 @@
"deprecated": "core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js.",
"hasInstallScript": true
},
"node_modules/cose-base": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/cose-base/-/cose-base-2.2.0.tgz",
"integrity": "sha512-AzlgcsCbUMymkADOJtQm3wO9S3ltPfYOFD5033keQn9NJzIbtnZj+UdBJe7DYml/8TdbtHJW3j58SOnKhWY/5g==",
"dependencies": {
"layout-base": "^2.0.0"
}
},
"node_modules/cosmiconfig": {
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz",
......@@ -4625,6 +4773,25 @@
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="
},
"node_modules/cytoscape": {
"version": "3.29.2",
"resolved": "https://registry.npmjs.org/cytoscape/-/cytoscape-3.29.2.tgz",
"integrity": "sha512-2G1ycU28Nh7OHT9rkXRLpCDP30MKH1dXJORZuBhtEhEW7pKwgPi77ImqlCWinouyE1PNepIOGZBOrE84DG7LyQ==",
"engines": {
"node": ">=0.10"
}
},
"node_modules/cytoscape-fcose": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/cytoscape-fcose/-/cytoscape-fcose-2.2.0.tgz",
"integrity": "sha512-ki1/VuRIHFCzxWNrsshHYPs6L7TvLu3DL+TyIGEsRcvVERmxokbf5Gdk7mFxZnTdiGtnA4cfSmjZJMviqSuZrQ==",
"dependencies": {
"cose-base": "^2.2.0"
},
"peerDependencies": {
"cytoscape": "^3.2.0"
}
},
"node_modules/damerau-levenshtein": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz",
......@@ -10388,6 +10555,11 @@
"node": ">=0.10"
}
},
"node_modules/layout-base": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/layout-base/-/layout-base-2.0.1.tgz",
"integrity": "sha512-dp3s92+uNI1hWIpPGH3jK2kxE2lMjdXdr+DH8ynZHpd6PUlH6x6cbuXnoMmiNumznqaNO31xu9e79F0uuZ0JFg=="
},
"node_modules/leven": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz",
......@@ -15078,126 +15250,6 @@
"type": "github",
"url": "https://github.com/sponsors/wooorm"
}
},
"node_modules/@next/swc-darwin-x64": {
"version": "14.2.3",
"resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.3.tgz",
"integrity": "sha512-6adp7waE6P1TYFSXpY366xwsOnEXM+y1kgRpjSRVI2CBDOcbRjsJ67Z6EgKIqWIue52d2q/Mx8g9MszARj8IEA==",
"cpu": [
"x64"
],
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@next/swc-linux-arm64-gnu": {
"version": "14.2.3",
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.3.tgz",
"integrity": "sha512-cuzCE/1G0ZSnTAHJPUT1rPgQx1w5tzSX7POXSLaS7w2nIUJUD+e25QoXD/hMfxbsT9rslEXugWypJMILBj/QsA==",
"cpu": [
"arm64"
],
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@next/swc-linux-arm64-musl": {
"version": "14.2.3",
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.3.tgz",
"integrity": "sha512-0D4/oMM2Y9Ta3nGuCcQN8jjJjmDPYpHX9OJzqk42NZGJocU2MqhBq5tWkJrUQOQY9N+In9xOdymzapM09GeiZw==",
"cpu": [
"arm64"
],
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@next/swc-linux-x64-gnu": {
"version": "14.2.3",
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.3.tgz",
"integrity": "sha512-ENPiNnBNDInBLyUU5ii8PMQh+4XLr4pG51tOp6aJ9xqFQ2iRI6IH0Ds2yJkAzNV1CfyagcyzPfROMViS2wOZ9w==",
"cpu": [
"x64"
],
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@next/swc-linux-x64-musl": {
"version": "14.2.3",
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.3.tgz",
"integrity": "sha512-BTAbq0LnCbF5MtoM7I/9UeUu/8ZBY0i8SFjUMCbPDOLv+un67e2JgyN4pmgfXBwy/I+RHu8q+k+MCkDN6P9ViQ==",
"cpu": [
"x64"
],
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@next/swc-win32-arm64-msvc": {
"version": "14.2.3",
"resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.3.tgz",
"integrity": "sha512-AEHIw/dhAMLNFJFJIJIyOFDzrzI5bAjI9J26gbO5xhAKHYTZ9Or04BesFPXiAYXDNdrwTP2dQceYA4dL1geu8A==",
"cpu": [
"arm64"
],
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@next/swc-win32-ia32-msvc": {
"version": "14.2.3",
"resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.3.tgz",
"integrity": "sha512-vga40n1q6aYb0CLrM+eEmisfKCR45ixQYXuBXxOOmmoV8sYST9k7E3US32FsY+CkkF7NtzdcebiFT4CHuMSyZw==",
"cpu": [
"ia32"
],
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@next/swc-win32-x64-msvc": {
"version": "14.2.3",
"resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.3.tgz",
"integrity": "sha512-Q1/zm43RWynxrO7lW4ehciQVj+5ePBhOK+/K2P7pLFX3JaJ/IZVC69SHidrmZSOkqz7ECIOhhy7XhAFG4JYyHA==",
"cpu": [
"x64"
],
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">= 10"
}
}
}
}
......@@ -9,6 +9,7 @@ import { TranslationsProvider } from '@/translations/translationsProvider';
import { EuiProvider, EuiThemeColorMode } from '@elastic/eui';
import '@elastic/eui/dist/eui_theme_dark.min.css';
import '@elastic/eui/dist/eui_theme_light.min.css';
import { EuiSideNavItemType } from '@elastic/eui/src/components/side_nav/side_nav_types';
import {
ApiClientContextProvider,
ColorModes,
......@@ -20,11 +21,13 @@ import {
WfoPageTemplate,
WfoToastsList,
defaultOrchestratorTheme,
WfoMenuItemLink,
} from '@orchestrator-ui/orchestrator-ui-components';
import { SessionProvider } from 'next-auth/react';
import { NextAdapter } from 'next-query-params';
import App, { AppContext, AppInitialProps, AppProps } from 'next/app';
import Head from 'next/head';
import { useRouter } from 'next/router';
import React, { useEffect, useState } from 'react';
import NoSSR from 'react-no-ssr';
import { QueryClient, QueryClientProvider } from 'react-query';
......@@ -48,6 +51,8 @@ function CustomApp({
pageProps,
orchestratorConfig,
}: AppProps & AppOwnProps) {
const router = useRouter();
const [queryClient] = useState(() => new QueryClient(queryClientConfig));
const [themeMode, setThemeMode] = useState<EuiThemeColorMode>(
ColorModes.LIGHT,
......@@ -84,6 +89,25 @@ function CustomApp({
return null;
}
const addMenuItems = (
defaultMenuItems: EuiSideNavItemType<object>[],
): EuiSideNavItemType<object>[] => [
...defaultMenuItems,
{
name: 'Maps',
id: '10',
isSelected: router.pathname === '/maps',
href: '/maps',
renderItem: () => (
<WfoMenuItemLink
path={'/maps'}
translationString="Maps"
isSelected={router.pathname === '/maps'}
/>
),
},
];
return (
<WfoErrorBoundary>
<OrchestratorConfigProvider
......@@ -113,6 +137,7 @@ function CustomApp({
<WfoPageTemplate
getAppLogo={getAppLogo}
onThemeSwitch={handleThemeSwitch}
overrideMenuItems={addMenuItems}
>
<QueryParamProvider
adapter={NextAdapter}
......
import NetworkMap, {
NetworkMapProps,
NetworkTopologyData,
} from '@/components/NetworkMap/NetworkMap';
import axios from 'axios';
import { NextPage, GetServerSideProps } from 'next';
import Head from 'next/head';
import React from 'react';
const Maps: NextPage<NetworkMapProps> = ({ data }) => {
return (
<>
<Head>
<title>Maps</title>
</Head>
<div>
<NetworkMap data={data} />
</div>
</>
);
};
export const getServerSideProps: GetServerSideProps = async () => {
try {
const response = await axios.get(process.env.NETWORK_TOPOLOGY_API_URL!);
const networkTopologyData: NetworkTopologyData = response.data;
return {
props: {
networkTopologyData,
},
};
} catch (error) {
console.error('Failed to fetch data', error);
return {
props: {
networkTopologyData: null,
},
};
}
};
export default Maps;
public/images/juniper_icon.png

16.1 KiB

public/images/nokia_icon.png

5.76 KiB

0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment