import { CaretDownOutlined } from '@ant-design/icons'; import { IconFont } from '@gpustack/core-ui'; import { Link, useLocation } from '@umijs/max'; import { Tooltip } from 'antd'; import { createStyles } from 'antd-style'; import React, { useMemo, useState } from 'react'; interface MenuItem { icon?: string; selectedIcon?: string; defaultIcon?: string; children?: MenuItem[]; [key: string]: any; } interface SiderMenuProps { menuData: MenuItem[]; collapsed?: boolean; initialState: Global.InitialStateType; } const useStyles = createStyles(({ css, token }) => { console.log('useStyles', token); // @ts-ignore const { Menu } = token; return { siderMenu: css` &.sider-menu-collapsed { .menu-item { justify-content: center; padding: 0; } } `, groupTitle: css` display: flex; align-items: center; gap: 8px; cursor: pointer; white-space: nowrap; padding: var(--ant-padding-xs) var(--ant-padding); font-size: 12px; padding-bottom: 4px; overflow: hidden; height: 30px; &:hover { .group-title-text { color: var(--ant-color-text); } } .anticon { transform: scale(0.8); } .group-title-text { display: flex; align-items: center; gap: 4px; font-size: 12px; color: var(--ant-color-text-tertiary); font-weight: 400; } &.menu-item-group-title-collapsed { position: relative; height: 1px; padding-block: 0; padding-inline: 0; justify-content: center; } `, menuItemContent: css` margin: 2px 0; border-radius: 4px; overflow: hidden; `, menuItemWrapper: css` display: flex; align-items: center; justify-content: flex-start; gap: 12px; cursor: pointer; position: relative; padding-inline: calc(var(--ant-font-size) * 2) var(--ant-padding); padding-left: 16px; overflow: hidden; white-space: nowrap; height: ${Menu.itemHeight}px; line-height: ${Menu.itemHeight}px; color: var(--ant-color-text-tertiary); &:hover { background-color: ${Menu.itemHoverBg}; color: ${Menu.itemHoverColor}; } &.menu-item-selected { background-color: ${Menu.itemSelectedBg}; color: ${Menu.itemSelectedColor}; .anticon { color: ${Menu.itemSelectedColor}; } } &:active { background-color: ${Menu.itemActiveBg}; color: ${Menu.itemActiveColor}; } .anticon { font-size: 16px; } .icon-wrapper { display: flex; align-items: center; justify-content: center; width: 100%; height: 100%; } `, menuItemGroup: css` &.menu-item-group-hidden { display: none; } `, line: css` height: 1px; margin-block: 6px; background-color: ${token.colorSplit}; position: absolute; left: -2px; right: -2px; ` }; }); const SiderMenu: React.FC = (props) => { const { menuData, collapsed, initialState } = props; const is_admin = initialState?.currentUser?.is_admin || false; const { styles, cx } = useStyles(); const location = useLocation(); const [collapseKeys, setCollapseKeys] = useState>(new Set()); console.log('SiderMenu', location.pathname); const dividerStyles = useMemo(() => { if (collapsed) { return { margin: '6px 0' }; } return { margin: '6px 16px', width: 'unset', minWidth: 'unset', maxWidth: 'unset' }; }, [collapsed]); const handleToggleGroup = (e: any, menuGroup: any) => { e.stopPropagation(); console.log('handleToggleGroup', menuGroup.key); if (collapseKeys.has(menuGroup.key)) { collapseKeys.delete(menuGroup.key); } else { collapseKeys.add(menuGroup.key); } setCollapseKeys(new Set(collapseKeys)); }; const menuItemRender = (menuItem: MenuItem, key: string) => { return (
{collapsed ? ( ) : ( <> {menuItem.name} )}
); }; return (
{menuData.map((item: MenuItem, index: number) => (
{item.children && item.children.length > 0 ? ( <>
handleToggleGroup(e, item)} > {!collapsed ? ( {item.name} ) : is_admin ? ( ) : null}
{item.children?.map((child: MenuItem) => menuItemRender(child, child.key) )}
) : ( menuItemRender(item, item.key) )}
))}
); }; export default SiderMenu;