66 lines
3.0 KiB
TypeScript
66 lines
3.0 KiB
TypeScript
import React from 'react';
|
|
import {useSelector} from 'react-redux';
|
|
import {useNavigate, useLocation} from 'react-router-dom';
|
|
import {Sidebar, SidebarHeader, SidebarContent} from '@/components/ui/sidebar';
|
|
import {MenuItem, MenuGroup} from '@/components/ui/sidebar-menu';
|
|
import type {RootState} from '@/store';
|
|
import {MenuTypeEnum} from '@/pages/System/Menu/types';
|
|
import {getIconComponent} from '@/config/icons';
|
|
|
|
interface AppMenuProps {
|
|
openKeys: string[];
|
|
onOpenChange: (keys: string[]) => void;
|
|
}
|
|
|
|
export function AppMenu({openKeys, onOpenChange}: AppMenuProps) {
|
|
const navigate = useNavigate();
|
|
const location = useLocation();
|
|
const menus = useSelector((state: RootState) => state.user.menus);
|
|
|
|
return (
|
|
<Sidebar>
|
|
<SidebarHeader>
|
|
<div className="text-lg font-semibold text-slate-900">Deploy Ease</div>
|
|
</SidebarHeader>
|
|
<SidebarContent>
|
|
<MenuGroup>
|
|
{menus?.filter(menu => menu.type !== MenuTypeEnum.BUTTON && !menu.hidden)
|
|
.map(menu => (
|
|
<MenuItem
|
|
key={menu.path || String(menu.id)}
|
|
icon={getIconComponent(menu.icon)}
|
|
title={menu.name}
|
|
active={location.pathname === menu.path}
|
|
expanded={openKeys.includes(menu.path || String(menu.id))}
|
|
onClick={() => {
|
|
if (menu.children?.length) {
|
|
onOpenChange(
|
|
openKeys.includes(menu.path || String(menu.id))
|
|
? openKeys.filter(key => key !== (menu.path || String(menu.id)))
|
|
: [...openKeys, menu.path || String(menu.id)]
|
|
);
|
|
} else if (menu.path) {
|
|
navigate(menu.path);
|
|
}
|
|
}}
|
|
>
|
|
{menu.children?.map(child => (
|
|
<MenuItem
|
|
key={child.path || String(child.id)}
|
|
icon={getIconComponent(child.icon)}
|
|
title={child.name}
|
|
active={location.pathname === child.path}
|
|
onClick={() => {
|
|
if (child.path) {
|
|
navigate(child.path);
|
|
}
|
|
}}
|
|
/>
|
|
))}
|
|
</MenuItem>
|
|
))}
|
|
</MenuGroup>
|
|
</SidebarContent>
|
|
</Sidebar>
|
|
);
|
|
}
|