diff --git a/frontend/src/components/AppMenu.tsx b/frontend/src/components/AppMenu.tsx
deleted file mode 100644
index e6e7f2e0..00000000
--- a/frontend/src/components/AppMenu.tsx
+++ /dev/null
@@ -1,66 +0,0 @@
-import React from 'react';
-import { useSelector } from 'react-redux';
-import { useNavigate, useLocation } from 'react-router-dom';
-import { Sidebar, SidebarHeader, SidebarContent } from './ui/sidebar';
-import { MenuItem, MenuGroup } from './ui/sidebar-menu';
-import type { RootState } from '@/store';
-import { MenuResponse, 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 (
-
-
- Deploy Ease
-
-
-
- {menus?.filter(menu => menu.type !== MenuTypeEnum.BUTTON && !menu.hidden)
- .map(menu => (
-
-
-
- );
-}
\ No newline at end of file
diff --git a/frontend/src/layouts/AppMenu.tsx b/frontend/src/layouts/AppMenu.tsx
new file mode 100644
index 00000000..3178f476
--- /dev/null
+++ b/frontend/src/layouts/AppMenu.tsx
@@ -0,0 +1,66 @@
+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 (
+
+
+ Deploy Ease
+
+
+
+ {menus?.filter(menu => menu.type !== MenuTypeEnum.BUTTON && !menu.hidden)
+ .map(menu => (
+ {
+ 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 => (
+ {
+ if (child.path) {
+ navigate(child.path);
+ }
+ }}
+ />
+ ))}
+
+ ))}
+
+
+
+ );
+}
\ No newline at end of file
diff --git a/frontend/src/layouts/BasicLayout.tsx b/frontend/src/layouts/BasicLayout.tsx
index 6625a027..28bbdb11 100644
--- a/frontend/src/layouts/BasicLayout.tsx
+++ b/frontend/src/layouts/BasicLayout.tsx
@@ -16,7 +16,7 @@ import {getWeather} from '../services/weather';
import type {RootState} from '../store';
import dayjs from 'dayjs';
import 'dayjs/locale/zh-cn';
-import { AppMenu } from '@/components/AppMenu';
+import { AppMenu } from './AppMenu';
import { Layout, LayoutContent, Header, Main } from '@/components/ui/layout';
const {confirm} = Modal;