Skip to content

Commit

Permalink
refactor(projects): refactor part of the menu code
Browse files Browse the repository at this point in the history
  • Loading branch information
Ohh-889 committed Sep 3, 2024
1 parent c59edf6 commit d19aa0b
Show file tree
Hide file tree
Showing 20 changed files with 356 additions and 114 deletions.
6 changes: 5 additions & 1 deletion eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@ export default defineConfig(
singleAttributePerLine: true,
trailingCommas: 'none'
},
ignores: ['src/layouts/modules/global-tab/index.tsx', 'ErrorBoundary.tsx']
ignores: [
'src/layouts/modules/global-menu/**/*.tsx',
'src/layouts/modules/global-tab/index.tsx',
'ErrorBoundary.tsx'
]
},
{
rules: {
Expand Down
4 changes: 4 additions & 0 deletions src/constants/app.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { transformRecordToOption } from '@/utils/common';

export const GLOBAL_HEADER_MENU_ID = '__GLOBAL_HEADER_MENU__';

export const GLOBAL_SIDER_MENU_ID = '__GLOBAL_SIDER_MENU__';

export const themeSchemaRecord: Record<UnionKey.ThemeScheme, App.I18n.I18nKey> = {
light: 'theme.themeSchema.light',
dark: 'theme.themeSchema.dark',
Expand Down
16 changes: 10 additions & 6 deletions src/layouts/base-layout/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { AdminLayout, LAYOUT_SCROLL_EL_ID } from '@sa/materials';
import type { LayoutMode } from '@sa/materials';
import { configResponsive } from 'ahooks';
import { Suspense } from 'react';
import './index.scss';
import {
getContentXScrollable,
Expand All @@ -19,6 +20,8 @@ import GlobalSider from '../modules/global-sider';
import ThemeDrawer from '../modules/theme-drawer';
import GlobalTab from '../modules/global-tab';

const GlobalMenu = lazy(() => import('../modules/global-menu'));

const LAYOUT_MODE_VERTICAL: LayoutMode = 'vertical';
const LAYOUT_MODE_HORIZONTAL: LayoutMode = 'horizontal';
const LAYOUT_MODE_VERTICAL_MIX = 'vertical-mix';
Expand Down Expand Up @@ -127,29 +130,30 @@ export function Component() {
rightFooter={themeSettings.footer.right}
Header={
<GlobalHeader
childrenMenu={childrenMenu}
{...headerProps}
settings={themeSettings}
isMobile={isMobile}
menus={menus}
/>
}
Tab={<GlobalTab />}
Sider={
<GlobalSider
isVerticalMix={isVerticalMix}
siderCollapse={siderCollapse}
themeSetting={themeSettings}
inverted={themeSettings.sider.inverted}
isHorizontalMix={isHorizontalMix}
childrenMenus={childrenMenu}
menus={menus}
isVertical={layoutMode === LAYOUT_MODE_VERTICAL}
headerHeight={themeSettings.header.height}
/>
}
Footer={<GlobalFooter />}
>
<GlobalContent />
<Suspense fallback={null}>
<GlobalMenu
mode={themeSettings.layout.mode}
menus={menus}
/>
</Suspense>
<ThemeDrawer />
</AdminLayout>
);
Expand Down
84 changes: 32 additions & 52 deletions src/layouts/modules/global-header/index.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import type { MenuProps } from 'antd';
import DarkModeContainer from '@/components/stateless/common/DarkModeContainer';
import ThemeSchemaSwitch from '@/components/stateful/ThemeSchemaSwitch';
import LangSwitch from '@/components/stateful/LangSwitch';
import FullScreen from '@/components/stateless/common/FullScreen';
import { GLOBAL_HEADER_MENU_ID } from '@/constants/app';
import GlobalLogo from '../global-logo';
import GlobalSearch from '../global-search';
import HorizontalMenu from '../global-menu/BaseMenu';
import GlobalBreadcrumb from '../global-breadcrumb';
import ThemeButton from './components/ThemeButton';
import UserAvatar from './components/UserAvatar';
Expand All @@ -17,65 +16,46 @@ interface Props {
showMenuToggler?: App.Global.HeaderProps['showMenuToggler'];
/** Whether to show the menu */
showMenu?: App.Global.HeaderProps['showMenu'];
childrenMenu: MenuProps['items'];
menus: MenuProps['items'];
isMobile: boolean;
settings: App.Theme.ThemeSetting;
}
const GlobalHeader: FC<Props> = memo(
({ showLogo, showMenuToggler, showMenu, childrenMenu, menus, isMobile, settings }) => {
const headerMenus = () => {
if (settings.layout.mode === 'horizontal') {
return menus;
}

if (settings.layout.mode === 'horizontal-mix') {
return childrenMenu;
}
const GlobalHeader: FC<Props> = memo(({ showLogo, showMenuToggler, showMenu, isMobile, settings }) => {
const [isFullscreen, { toggleFullscreen }] = useFullscreen(document.body);

return [];
};
return (
<DarkModeContainer className="h-full flex-y-center px-12px shadow-header">
{showLogo && (
<GlobalLogo
className="h-full"
style={{ width: `${settings.sider.width}px` }}
/>
)}
{showMenuToggler && <MenuToggler />}

const [isFullscreen, { toggleFullscreen }] = useFullscreen(document.body);
<div
id={GLOBAL_HEADER_MENU_ID}
className="h-full flex-y-center flex-1-hidden"
>
{!isMobile && !showMenu && <GlobalBreadcrumb className="ml-12px" />}
</div>

return (
<DarkModeContainer className="h-full flex-y-center px-12px shadow-header">
{showLogo && (
<GlobalLogo
className="h-full"
style={{ width: `${settings.sider.width}px` }}
/>
)}

{showMenu ? (
<HorizontalMenu
menus={headerMenus()}
mode="horizontal"
<div className="h-full flex-y-center justify-end">
<GlobalSearch />
{!isMobile && (
<FullScreen
className="px-12px"
full={isFullscreen}
toggleFullscreen={toggleFullscreen}
/>
) : (
<div className="h-full flex-y-center flex-1-hidden">
{showMenuToggler && <MenuToggler />}
{!isMobile && <GlobalBreadcrumb className="ml-12px" />}
</div>
)}
<div className="h-full flex-y-center justify-end">
<GlobalSearch />
{!isMobile && (
<FullScreen
className="px-12px"
full={isFullscreen}
toggleFullscreen={toggleFullscreen}
/>
)}
<LangSwitch className="px-12px" />
<ThemeSchemaSwitch className="px-12px" />
<ThemeButton />
<UserAvatar />
</div>
</DarkModeContainer>
);
}
);
<LangSwitch className="px-12px" />
<ThemeSchemaSwitch className="px-12px" />
<ThemeButton />
<UserAvatar />
</div>
</DarkModeContainer>
);
});

export default GlobalHeader;
7 changes: 3 additions & 4 deletions src/layouts/modules/global-menu/BaseMenu.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import type { MenuProps } from 'antd';
import { Menu } from 'antd';
import { SimpleScrollbar } from '@sa/materials';
import { useRoute } from '@sa/simple-router';
import type { MenuInfo } from 'rc-menu/lib/interface';
Expand Down Expand Up @@ -110,7 +109,7 @@ const BaseMenu: FC<Props> = memo(({ mode = 'inline', menus, darkTheme, className

return (
<SimpleScrollbar className={className}>
<Menu
<AMenu
mode={mode}
items={menus}
theme={darkTheme ? 'dark' : 'light'}
Expand All @@ -123,8 +122,8 @@ const BaseMenu: FC<Props> = memo(({ mode = 'inline', menus, darkTheme, className
'bg-container ': !darkTheme,
'horizontal-menu': isHorizontal
})}
onClick={handleClickMenu}
></Menu>
onSelect={handleClickMenu}
/>
</SimpleScrollbar>
);
});
Expand Down
2 changes: 1 addition & 1 deletion src/layouts/modules/global-menu/HorizontalMixMenu.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { SubMenuType } from 'antd/es/menu/interface';
import { useRouter } from '@sa/simple-router';
import { setActiveFirstLevelMenuKey } from '@/store/slice/tab';
import FirstLevelMenu from './FirstLevelMenu';
import FirstLevelMenu from './components/FirstLevelMenu';

const HorizontalMixMenu = memo(() => {
const dispatch = useAppDispatch();
Expand Down
2 changes: 1 addition & 1 deletion src/layouts/modules/global-menu/VerticalMixMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import DarkModeContainer from '@/components/stateless/common/DarkModeContainer';
import { setActiveFirstLevelMenuKey } from '@/store/slice/tab';
import PinToggler from '@/components/stateless/common/PinToggler';
import { getActiveFirstLevelMenuKey } from '@/store/slice/tab/shared';
import FirstLevelMenu from './FirstLevelMenu';
import FirstLevelMenu from './components/FirstLevelMenu';
import BaseMenu from './BaseMenu';
interface Props {
menus: MenuProps['items'];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@ import { cloneElement } from 'react';
import { getSiderCollapse } from '@/store/slice/app';
import { getDarkMode, getThemeSettings } from '@/store/slice/theme';
import { selectActiveFirstLevelMenuKey } from '@/store/slice/tab';

interface Props {
inverted?: boolean;
children?: React.ReactNode;
onSelect: (menu: SubMenuType) => void;
}

interface MixMenuItemProps {
/** Menu item label */
label: React.ReactNode;
Expand All @@ -26,6 +28,7 @@ interface MixMenuItemProps {
function MixMenuItem({ label, Icon, active, isMini, inverted, onClick }: MixMenuItemProps) {
const themeSettings = useAppSelector(getThemeSettings);
const darkMode = useAppSelector(getDarkMode);

const selectedBgColor = useMemo(() => {
const light = transformColorWithOpacity(themeSettings.themeColor, 0.1, '#ffffff');
const dark = transformColorWithOpacity(themeSettings.themeColor, 0.3, '#000000');
Expand Down Expand Up @@ -63,6 +66,7 @@ const FirstLevelMenu: FC<Props> = memo(({ children, inverted, onSelect }) => {

const siderCollapse = useAppSelector(getSiderCollapse);
const activeMenuKey = useAppSelector(selectActiveFirstLevelMenuKey);

return (
<div className="h-full flex-col-stretch flex-1-hidden">
{children}
Expand All @@ -75,7 +79,7 @@ const FirstLevelMenu: FC<Props> = memo(({ children, inverted, onSelect }) => {
Icon={item.icon}
label={item.label}
key={item?.key}
></MixMenuItem>
/>
))}
</SimpleScrollbar>
<MenuToggler
Expand Down
30 changes: 30 additions & 0 deletions src/layouts/modules/global-menu/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import type { MenuProps } from 'antd';
import { createPortal } from 'react-dom';
import { GLOBAL_HEADER_MENU_ID, GLOBAL_SIDER_MENU_ID } from '@/constants/app';
import VerticalMixMenu from './modules/VerticalMixMenu';
import HorizontalMenu from './modules/HorizontalMenu';
import HorizontalMixMenu from './modules/HorizontalMixMenu';

interface Props {
mode: UnionKey.ThemeLayoutMode;
menus: MenuProps['items'];
}

const headerContainer = document.getElementById(GLOBAL_HEADER_MENU_ID);

const siderContainer = document.getElementById(GLOBAL_SIDER_MENU_ID);

const GlobalMenu: FC<Props> = memo(({ mode, menus }) => {
if (!headerContainer || !siderContainer) return null;

const componentsMap = {
vertical: createPortal(<VerticalMixMenu menus={menus} />, siderContainer),
'vertical-mix': <VerticalMixMenu menus={menus} />,
horizontal: createPortal(<HorizontalMenu />, headerContainer),
'horizontal-mix': <HorizontalMixMenu />
};

return componentsMap[mode];
});

export default GlobalMenu;
45 changes: 45 additions & 0 deletions src/layouts/modules/global-menu/modules/HorizontalMenu.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import {useRoute} from '@sa/simple-router'
import type {RouteLocationNormalizedLoaded} from '@sa/simple-router'
import type { MenuInfo } from 'rc-menu/lib/interface';
import { headerContainer } from './shared';
import {useRouterPush} from '@/hooks/common/routerPush'



const HorizontalMenu = () => {
if (!headerContainer) return null;

const route = useRoute();

console.log(route);


const menus = useMenu();

const router = useRouterPush();
function getSelectKey(route:RouteLocationNormalizedLoaded) {
const { hideInMenu, activeMenu } = route.meta;
const name = route.name as string;

const routeName = (hideInMenu ? activeMenu : name) || name;

return [routeName];
};

const selectKey=getSelectKey(route)

function handleClickMenu(menuInfo: MenuInfo) {
router.menuPush(menuInfo.key);
}


return <AMenu
mode='horizontal'
items={menus}
inlineIndent={18}
onSelect={handleClickMenu}
selectedKeys={selectKey}
/>;
};

export default HorizontalMenu;
Loading

0 comments on commit d19aa0b

Please sign in to comment.