blob: 72be9351c3f9b9c5cd46e0360452019c7ad5bb5e [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import React, { FC, ReactNode, useState } from 'react';
import {
Box,
BoxProps,
Button,
Flex,
useColorModeValue,
Image,
} from '@chakra-ui/react';
import { IconType } from 'react-icons';
import { ArrowBackIcon } from '@chakra-ui/icons';
import { useRouter } from 'next/router';
import {
FiList, FiGrid, FiServer, FiDatabase, FiMenu,
} from 'react-icons/fi';
import LogoImg from '../../static/images/logo.png';
import { MenuItem, MenuGroupItem } from './MenuItem';
const Menus: Array<{
group?: string;
name: string;
icon: IconType;
href: string;
subPath?:string[]
}> = [
{ name: 'Overview', icon: FiList, href: '/' },
{ name: 'Metrics', icon: FiMenu, href: '/metrics' },
{ name: 'Registry', icon: FiDatabase, href: '/registry' },
{ name: 'Topic', icon: FiGrid, href: '/topic' },
{ name: 'Event', icon: FiDatabase, href: '/event' },
{
group: 'Workflow',
name: 'Workflows',
icon: FiServer,
href: '/workflows',
subPath: ['/workflows/create'],
},
{
group: 'Workflow',
name: 'Event Catalogs',
icon: FiServer,
href: '/eventCatalogs',
},
{
group: 'Clients',
name: 'TCP',
icon: FiServer,
href: '/tcp',
},
{
group: 'Clients',
name: 'HTTP',
icon: FiServer,
href: '/http',
},
{
group: 'Clients',
name: 'gRPC',
icon: FiServer,
href: '/grpc',
},
];
interface MenuProps extends BoxProps {
onClose: () => void;
}
interface IGroupItem {
name?: string;
children: ReactNode[];
}
const NavMenu: FC<MenuProps> = ({ display = {}, onClose }) => {
const router = useRouter();
const [curMenu, setCurMenu] = useState('');
const curRoute = router.pathname;
const MenuByGroup = Menus.reduce<{
[groupName: string]: IGroupItem;
}>(
(groupItems, item) => {
const {
group, name, href, subPath,
} = item;
const menuItem = (
<MenuItem
key={`menu_item_${name}`}
selected={curRoute === href || (subPath?.includes(curRoute) ?? false)}
active={curMenu === group}
href={href}
setActiveName={(selectedName:string) => setCurMenu(selectedName)}
>
{name}
</MenuItem>
);
if (!group) {
groupItems.topMenu.children.push(menuItem);
return groupItems;
}
if (!groupItems[group]) {
groupItems[group] = { name: group, children: [] };
}
groupItems[group].children.push(menuItem);
return groupItems;
},
{ topMenu: { children: [] } },
);
return (
<Box
display={display}
pos="fixed"
w={{ base: 'full', md: 60 }}
borderRight="1px"
borderRightColor={useColorModeValue('gray.200', 'gray.700')}
h="full"
bg={useColorModeValue('white', 'gray.900')}
boxShadow="base"
>
<Flex
mt={{ base: 5, md: 10 }}
mb={{ base: 5, md: 10 }}
alignItems={{ base: 'space-between', md: 'center' }}
justifyContent={{ base: 'space-between', md: 'center' }}
w={{ base: 'full' }}
>
<Image
display={{ base: 'none', md: 'block' }}
w={100}
src={LogoImg.src}
alt="Dan Abramov"
/>
<Button
display={{ base: 'block', md: 'none' }}
w={{ base: 'full' }}
size="lg"
textAlign="left"
onClick={onClose}
>
<ArrowBackIcon mr={2} />
Back
</Button>
</Flex>
<Flex flexDirection="column" alignItems="center">
{Object.entries(MenuByGroup).map((groupItem) => (
<MenuGroupItem key={`group_item_${groupItem[1].name}`} name={groupItem[1].name ?? ''}>
{groupItem[1].children}
</MenuGroupItem>
))}
</Flex>
</Box>
);
};
export default NavMenu;