diff --git a/ui/src/pages/ConsoleLayout.tsx b/ui/src/pages/ConsoleLayout.tsx index 652a7eba..bc5d6b2f 100644 --- a/ui/src/pages/ConsoleLayout.tsx +++ b/ui/src/pages/ConsoleLayout.tsx @@ -1,7 +1,7 @@ -import { useEffect, useState } from "react"; +import React, { useEffect, useState } from "react"; import { Link, Navigate, Outlet, useLocation, useNavigate } from "react-router-dom"; import { useTranslation } from "react-i18next"; -import { Button, Dropdown, Layout, Menu, Tooltip, theme, type ButtonProps, type MenuProps } from "antd"; +import { Button, Drawer, Dropdown, Layout, Menu, Tooltip, theme, type ButtonProps, type MenuProps } from "antd"; import { Languages as LanguagesIcon, LogOut as LogOutIcon, @@ -21,65 +21,21 @@ import { getPocketBase } from "@/repository/pocketbase"; import { ConfigProvider } from "@/providers/config"; const ConsoleLayout = () => { - const location = useLocation(); const navigate = useNavigate(); const { t } = useTranslation(); const { token: themeToken } = theme.useToken(); - const { theme: browserTheme } = useTheme(); - const menuItems: Required["items"] = [ - { - key: "/", - icon: , - label: t("dashboard.page.title"), - onClick: () => navigate("/"), - }, - { - key: "/workflows", - icon: , - label: t("workflow.page.title"), - onClick: () => navigate("/workflows"), - }, - { - key: "/certificates", - icon: , - label: t("certificate.page.title"), - onClick: () => navigate("/certificates"), - }, - { - key: "/accesses", - icon: , - label: t("access.page.title"), - onClick: () => navigate("/accesses"), - }, - ]; - const [menuSelectedKey, setMenuSelectedKey] = useState(); + const [siderOpen, setSiderOpen] = useState(false); - const getActiveMenuItem = () => { - const item = - menuItems.find((item) => item!.key === location.pathname) ?? - menuItems.find((item) => item!.key !== "/" && location.pathname.startsWith(item!.key as string)); - return item; + const handleSiderOpen = () => { + setSiderOpen(true); }; - useEffect(() => { - const item = getActiveMenuItem(); - if (item) { - setMenuSelectedKey(item.key as string); - } else { - setMenuSelectedKey(undefined); - } - }, [location.pathname]); - - useEffect(() => { - if (menuSelectedKey && menuSelectedKey !== getActiveMenuItem()?.key) { - navigate(menuSelectedKey); - } - }, [menuSelectedKey]); - - // TODO: 响应式侧边栏菜单 + const handleSiderClose = () => { + setSiderOpen(false); + }; const handleLogoutClick = () => { auth.clear(); @@ -99,22 +55,10 @@ const ConsoleLayout = () => { <> - +
- - - Certimate - -
- { - setMenuSelectedKey(key); - }} - /> +
+
@@ -125,7 +69,22 @@ const ConsoleLayout = () => {
-
{/*
+
+
@@ -155,7 +114,99 @@ const ConsoleLayout = () => { ); }; -const ThemeToggleButton = ({ size }: { size?: ButtonProps["size"] }) => { +const SiderMenu = React.memo(({ onSelect }: { onSelect?: (key: string) => void }) => { + const location = useLocation(); + const navigate = useNavigate(); + + const { t } = useTranslation(); + + const MENU_KEY_HOME = "/"; + const MENU_KEY_WORKFLOWS = "/workflows"; + const MENU_KEY_CERTIFICATES = "/certificates"; + const MENU_KEY_ACCESSES = "/accesses"; + const menuItems: Required["items"] = [ + { + key: MENU_KEY_HOME, + icon: , + label: t("dashboard.page.title"), + onClick: () => { + navigate(MENU_KEY_HOME); + onSelect?.(MENU_KEY_HOME); + }, + }, + { + key: MENU_KEY_WORKFLOWS, + icon: , + label: t("workflow.page.title"), + onClick: () => { + navigate(MENU_KEY_WORKFLOWS); + onSelect?.(MENU_KEY_WORKFLOWS); + }, + }, + { + key: MENU_KEY_CERTIFICATES, + icon: , + label: t("certificate.page.title"), + onClick: () => { + navigate(MENU_KEY_CERTIFICATES); + onSelect?.(MENU_KEY_CERTIFICATES); + }, + }, + { + key: MENU_KEY_ACCESSES, + icon: , + label: t("access.page.title"), + onClick: () => { + navigate(MENU_KEY_ACCESSES); + onSelect?.(MENU_KEY_ACCESSES); + }, + }, + ]; + const [menuSelectedKey, setMenuSelectedKey] = useState(); + + const getActiveMenuItem = () => { + const item = + menuItems.find((item) => item!.key === location.pathname) ?? + menuItems.find((item) => item!.key !== MENU_KEY_HOME && location.pathname.startsWith(item!.key as string)); + return item; + }; + + useEffect(() => { + const item = getActiveMenuItem(); + if (item) { + setMenuSelectedKey(item.key as string); + } else { + setMenuSelectedKey(undefined); + } + }, [location.pathname]); + + useEffect(() => { + if (menuSelectedKey && menuSelectedKey !== getActiveMenuItem()?.key) { + navigate(menuSelectedKey); + } + }, [menuSelectedKey]); + + return ( + <> + + + Certimate + +
+ { + setMenuSelectedKey(key); + }} + /> +
+ + ); +}); + +const ThemeToggleButton = React.memo(({ size }: { size?: ButtonProps["size"] }) => { const { t } = useTranslation(); const { theme, setThemeMode } = useTheme(); @@ -183,9 +234,9 @@ const ThemeToggleButton = ({ size }: { size?: ButtonProps["size"] }) => {