diff --git a/.changeset/eighty-pandas-roll.md b/.changeset/eighty-pandas-roll.md new file mode 100644 index 0000000000..c4980f97f8 --- /dev/null +++ b/.changeset/eighty-pandas-roll.md @@ -0,0 +1,5 @@ +--- +"@scow/lib-web": patch +--- + +UI扩展修复当跳往扩展页面的导航项位于已有导航项的下面时,此扩展页面的导航结构不显示的问题 diff --git a/apps/portal-web/config/portal.yaml b/apps/portal-web/config/portal.yaml index 84f0bbc012..0d104fde63 100644 --- a/apps/portal-web/config/portal.yaml +++ b/apps/portal-web/config/portal.yaml @@ -84,5 +84,5 @@ shell: true # children: [] uiExtension: - - name: test1 + - name: test测试 url: http://localhost:16566 diff --git a/libs/web/src/extensions/navigations.tsx b/libs/web/src/extensions/navigations.tsx index a6ce70be56..500179930d 100644 --- a/libs/web/src/extensions/navigations.tsx +++ b/libs/web/src/extensions/navigations.tsx @@ -94,7 +94,9 @@ export const toNavItemProps = ( if (isUrl(returnedPath)) { return returnedPath; } const parts = ["/extensions"]; - if (extensionName) { parts.push(extensionName); } + if (extensionName) { + parts.push(encodeURIComponent(extensionName)); + } parts.push(returnedPath); return join(...parts); }; diff --git a/libs/web/src/layouts/base/BaseLayout.tsx b/libs/web/src/layouts/base/BaseLayout.tsx index a597aa3371..0cfedf8bc8 100644 --- a/libs/web/src/layouts/base/BaseLayout.tsx +++ b/libs/web/src/layouts/base/BaseLayout.tsx @@ -24,9 +24,9 @@ import { NavbarLink, navbarLinksRoute } from "src/extensions/navbarLinks"; import { fromNavItemProps, rewriteNavigationsRoute, toNavItemProps } from "src/extensions/navigations"; import { callExtensionRoute } from "src/extensions/routes"; import { UiExtensionStoreData } from "src/extensions/UiExtensionStore"; +import { calcActiveKeys } from "src/layouts/base/common"; import { Footer } from "src/layouts/base/Footer"; import { Header, HeaderNavbarLink } from "src/layouts/base/header"; -import { match } from "src/layouts/base/matchers"; import { SideNav } from "src/layouts/base/SideNav"; import { NavItemProps, UserInfo, UserLink } from "src/layouts/base/types"; import { useDarkMode } from "src/layouts/darkMode"; @@ -126,12 +126,19 @@ export const BaseLayout: React.FC> = ({ const finalRoutes = finalRoutesData ?? routes; - const firstLevelRoute = finalRoutes.find((x) => match(x, router.asPath)); + const activeKeys = useMemo(() => + finalRoutes + ? [...calcActiveKeys(finalRoutes, router.asPath)] + : [] + , [finalRoutes, router.asPath]); + + const firstLevelRoute = finalRoutes.find((x) => activeKeys.includes(x.path)); const sidebarRoutes = md ? firstLevelRoute?.children : finalRoutes; const hasSidebar = arrayContainsElement(sidebarRoutes); + // navbar links const { data: extensionNavbarLinks } = useAsync({ promiseFn: useCallback(async () => { @@ -194,11 +201,13 @@ export const BaseLayout: React.FC> = ({ languageId={languageId} right={headerRightContent} navbarLinks={[...extensionNavbarLinks ?? [], ...headerNavbarLinks ?? []]} + activeKeys={activeKeys} /> { hasSidebar ? ( = ({ - collapsed, routes, setCollapsed, pathname, + collapsed, routes, setCollapsed, pathname, activeKeys, }) => { const parentKeys = useMemo(() => getAllParentKeys(routes), [routes]); @@ -118,14 +119,12 @@ export const SideNav: React.FC = ({ }, [openKeys, parentKeys]); - const selectedKeys = useMemo(() => calcSelectedKeys(routes, pathname), [routes, pathname]); - // 账户管理页面,联动横向菜单栏展开相应的侧面菜单栏 useEffect(() => { if (menuFocusedRef.current) { - setOpenKeys([selectedKeys[1]]); + setOpenKeys([activeKeys[1]]); } - }, [selectedKeys]); + }, [activeKeys]); useEffect(() => { if (window.innerWidth <= antdBreakpoints[breakpoint]) { @@ -152,7 +151,7 @@ export const SideNav: React.FC = ({ > { - return links.reduce((prev, curr) => { - if (arrayContainsElement(curr.children)) { - prev.push(...calcSelectedKeys(curr.children, pathname)); + const selectedKeys = new Set(); + + for (const link of links) { + if (arrayContainsElement(link.children)) { + const childrenSelectedKeys = calcActiveKeys(link.children, pathname); + for (const childKey of childrenSelectedKeys) { + selectedKeys.add(childKey); + } } + if ( - (curr.path === "/" && pathname === "/") || - (curr.path !== "/" && curr.path !== "" && match(curr, pathname)) + link.children?.some((x) => selectedKeys.has(x.path)) || + (link.path === "/" && pathname === "/") || + (link.path !== "/" && link.path !== "" && match(link, pathname)) ) { - prev.push(curr.path); + selectedKeys.add(link.path); } + } - return prev; - }, [] as string[]); + return selectedKeys; } diff --git a/libs/web/src/layouts/base/header/BigScreenMenu.tsx b/libs/web/src/layouts/base/header/BigScreenMenu.tsx index 8e3210ed4a..be1784e344 100644 --- a/libs/web/src/layouts/base/header/BigScreenMenu.tsx +++ b/libs/web/src/layouts/base/header/BigScreenMenu.tsx @@ -14,9 +14,9 @@ import { arrayContainsElement } from "@scow/utils"; import { Menu } from "antd"; -import Router from "next/router"; -import React, { useMemo } from "react"; -import { calcSelectedKeys, createMenuItems, EXTERNAL_URL_PREFIX } from "src/layouts/base/common"; +import { useRouter } from "next/router"; +import React from "react"; +import { createMenuItems, EXTERNAL_URL_PREFIX } from "src/layouts/base/common"; import { antdBreakpoints } from "src/layouts/base/constants"; import { NavItemProps } from "src/layouts/base/types"; import { styled } from "styled-components"; @@ -41,17 +41,14 @@ interface Props { routes?: NavItemProps[]; className?: string; pathname: string; + activeKeys: string[]; } export const BigScreenMenu: React.FC = ({ - routes, className, pathname, + routes, className, pathname, activeKeys, }) => { - const selectedKeys = useMemo(() => - routes - ? calcSelectedKeys(routes, pathname) - : [] - , [routes, pathname]); + const router = useRouter(); const handleMenuClick = (e: any) => { const clickedRoute = routes?.find((route) => route.path === e.key); @@ -64,7 +61,7 @@ export const BigScreenMenu: React.FC = ({ if (EXTERNAL_URL_PREFIX.some((pref) => target.startsWith(pref))) { window.location.href = target; } else { - void Router.push(target); + void router.push(target); } } } @@ -79,7 +76,7 @@ export const BigScreenMenu: React.FC = ({ style={{ minWidth: 0, flex: "auto", border: 0 }} theme="light" mode="horizontal" - selectedKeys={selectedKeys} + selectedKeys={activeKeys} onClick={handleMenuClick} items={createMenuItems(routes, true)} /> diff --git a/libs/web/src/layouts/base/header/index.tsx b/libs/web/src/layouts/base/header/index.tsx index 9a0e09964c..0742baa3c0 100644 --- a/libs/web/src/layouts/base/header/index.tsx +++ b/libs/web/src/layouts/base/header/index.tsx @@ -86,6 +86,7 @@ interface Props { languageId: string; right?: React.ReactNode; navbarLinks?: HeaderNavbarLink[]; + activeKeys: string[]; } @@ -94,7 +95,7 @@ export const Header: React.FC = ({ setSidebarCollapsed, sidebarCollapsed, pathname, user, logout, basePath, userLinks, - languageId, + languageId, activeKeys, navbarLinks, right, }) => { @@ -132,6 +133,7 @@ export const Header: React.FC = ({