Skip to content

Commit

Permalink
refactor: nav refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
d3george authored and d3george committed Nov 7, 2024
1 parent e711d0a commit 44fe6c3
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 44 deletions.
26 changes: 14 additions & 12 deletions src/layouts/dashboard/nav/nav-horizontal.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
import { Menu, MenuProps } from 'antd';
import { useMemo, useState } from 'react';
import { useNavigate, useMatches } from 'react-router-dom';

import { useRouteToMenuFn, usePermissionRoutes, useFlattenedRoutes } from '@/router/hooks';
import { useMemo } from 'react';
import { useNavigate } from 'react-router-dom';

import {
useRouteToMenuFn,
usePermissionRoutes,
useFlattenedRoutes,
usePathname,
} from '@/router/hooks';
import { menuFilter } from '@/router/utils';
import { useThemeToken } from '@/theme/hooks';

import { NAV_HORIZONTAL_HEIGHT } from '../config';

export default function NavHorizontal() {
const navigate = useNavigate();
const matches = useMatches();
const pathname = usePathname();
const { colorBgElevated } = useThemeToken();

const routeToMenuFn = useRouteToMenuFn();
Expand All @@ -22,13 +27,10 @@ export default function NavHorizontal() {
return routeToMenuFn(menuRoutes);
}, [routeToMenuFn, permissionRoutes]);

const [currentOpenKeys, setCurrentOpenKeys] = useState<string[]>(() => {
return matches.filter((match) => match.pathname !== '/').map((match) => match.pathname);
});
const onClick: MenuProps['onClick'] = ({ key, keyPath }) => {
const nextLink = flattenedRoutes?.find((el) => el.key === key);
setCurrentOpenKeys(keyPath);
const selectedKeys = useMemo(() => [pathname], [pathname]);

const onClick: MenuProps['onClick'] = ({ key }) => {
const nextLink = flattenedRoutes?.find((el) => el.key === key);
// Handle special case for external links in menu items
// For external links: skip internal routing, avoid adding new tab in current project,
// prevent selecting current route, and open link in new browser tab
Expand All @@ -45,7 +47,7 @@ export default function NavHorizontal() {
mode="horizontal"
items={menuList}
defaultOpenKeys={[]}
defaultSelectedKeys={currentOpenKeys}
selectedKeys={selectedKeys}
onClick={onClick}
className="!z-10 !border-none"
style={{ background: colorBgElevated }}
Expand Down
72 changes: 40 additions & 32 deletions src/layouts/dashboard/nav/nav-vertical.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
import { Menu, MenuProps } from 'antd';
import Color from 'color';
import { useCallback, useMemo, useState } from 'react';
import { useMemo, useState } from 'react';
import { useMatches, useNavigate } from 'react-router-dom';

import Scrollbar from '@/components/scrollbar';
import { useRouteToMenuFn, usePermissionRoutes, useFlattenedRoutes } from '@/router/hooks';
import {
useRouteToMenuFn,
usePermissionRoutes,
useFlattenedRoutes,
usePathname,
} from '@/router/hooks';
import { menuFilter } from '@/router/utils';
import { useSettingActions, useSettings } from '@/store/settingStore';
import { useThemeToken } from '@/theme/hooks';
Expand All @@ -22,6 +27,7 @@ export default function NavVertical(props: Props) {
const navigate = useNavigate();
const matches = useMatches();
const { colorBgElevated, colorBorder } = useThemeToken();
const pathname = usePathname();

const settings = useSettings();
const { themeLayout } = settings;
Expand All @@ -31,27 +37,32 @@ export default function NavVertical(props: Props) {
const permissionRoutes = usePermissionRoutes();
const flattenedRoutes = useFlattenedRoutes();

const [collapsed, setCollapsed] = useState(themeLayout === ThemeLayout.Mini);
const menuList = useMemo(() => {
const menuRoutes = menuFilter(permissionRoutes);
return routeToMenuFn(menuRoutes);
}, [routeToMenuFn, permissionRoutes]);

const [currentOpenKeys, setCurrentOpenKeys] = useState<string[]>(() => {
return matches.filter((match) => match.pathname !== '/').map((match) => match.pathname);
});
const selectedKeys = useMemo(() => [pathname], [pathname]);
const openKeys = useMemo(() => {
const keys = matches
.filter((match) => match.pathname !== '/')
.filter((match) => match.pathname !== pathname)
.map((match) => match.pathname);
return keys;
}, [matches, pathname]);

const collapsed = useMemo(() => themeLayout === ThemeLayout.Mini, [themeLayout]);

const handleToggleCollapsed = useCallback(() => {
const handleToggleCollapsed = () => {
setSettings({
...settings,
themeLayout: collapsed ? ThemeLayout.Vertical : ThemeLayout.Mini,
});
}, [collapsed, settings, setSettings]);
setCollapsed(!collapsed);
};

const onClick: MenuProps['onClick'] = ({ key, keyPath }) => {
console.log('click', key, keyPath);
const nextLink = flattenedRoutes?.find((el) => el.key === key);
setCurrentOpenKeys(keyPath);
// Handle special case for external links in menu items
// For external links: skip internal routing, avoid adding new tab in current project,
// prevent selecting current route, and open link in new browser tab
Expand All @@ -65,29 +76,26 @@ export default function NavVertical(props: Props) {
};

return (
<div className="z-50 h-full flex-shrink-0">
<div
className="flex h-full flex-col"
style={{
width: collapsed ? NAV_COLLAPSED_WIDTH : NAV_WIDTH,
borderRight: `1px dashed ${Color(colorBorder).alpha(0.6).toString()}`,
}}
>
<NavLogo collapsed={collapsed} onToggle={handleToggleCollapsed} />
<div
style={{
width: collapsed ? NAV_COLLAPSED_WIDTH : NAV_WIDTH,
borderRight: `1px dashed ${Color(colorBorder).alpha(0.6).toString()}`,
}}
>
<NavLogo collapsed={collapsed} onToggle={handleToggleCollapsed} />

<Scrollbar style={{ height: `calc(100vh - ${HEADER_HEIGHT}px)` }}>
<Menu
mode="inline"
inlineCollapsed={collapsed}
items={menuList}
defaultOpenKeys={themeLayout === ThemeLayout.Vertical ? currentOpenKeys : []}
defaultSelectedKeys={currentOpenKeys}
style={{ backgroundColor: colorBgElevated }}
className="h-full !border-none"
onClick={onClick}
/>
</Scrollbar>
</div>
<Scrollbar style={{ height: `calc(100vh - ${HEADER_HEIGHT}px)` }}>
<Menu
mode="inline"
inlineCollapsed={collapsed}
items={menuList}
{...(!collapsed && { openKeys })}
selectedKeys={selectedKeys}
style={{ backgroundColor: colorBgElevated }}
className="h-full !border-none"
onClick={onClick}
/>
</Scrollbar>
</div>
);
}

0 comments on commit 44fe6c3

Please sign in to comment.