diff --git a/etc/brick-types.api.md b/etc/brick-types.api.md index fae7bc1598..2de1a25783 100644 --- a/etc/brick-types.api.md +++ b/etc/brick-types.api.md @@ -1387,6 +1387,8 @@ export interface MenuRawData { // (undocumented) menuId: string; // (undocumented) + overrideApp?: MicroApp; + // (undocumented) title: string; // Warning: (ae-forgotten-export) The symbol "TitleDataSource" needs to be exported by the entry point index.d.ts // diff --git a/packages/brick-kit/src/internal/menu.spec.ts b/packages/brick-kit/src/internal/menu.spec.ts index 9048946b32..659a954423 100644 --- a/packages/brick-kit/src/internal/menu.spec.ts +++ b/packages/brick-kit/src/internal/menu.spec.ts @@ -183,6 +183,10 @@ const mockMenuList: any[] = [ appId: "hola", }, ], + overrideApp: { + id: "hola", + homepage: "/hola", + }, }, { menuId: "menu-g", @@ -405,6 +409,7 @@ describe("constructMenu", () => { clearMenuTitleCache(); clearMenuCache(); jest.clearAllMocks(); + window.STANDALONE_MICRO_APPS = false; }); const context = { @@ -550,6 +555,54 @@ describe("constructMenu", () => { expect(fakeKernel.fulfilStoryboardI18n).toBeCalledWith(["hola"]); }); + it("should construct menu with override app in standalone mode", async () => { + const menuBar = { + menuId: "menu-f", + }; + const fakeKernel = { + fulfilStoryboardI18n: jest.fn(), + getStandaloneMenus: jest.fn((menuId, isPrefetch) => { + return Promise.resolve( + mockMenuList.filter((item) => item.menuId === menuId) + ); + }), + } as unknown as Kernel; + window.STANDALONE_MICRO_APPS = true; + await constructMenu(menuBar, context, fakeKernel); + expect(menuBar).toEqual({ + menuId: "menu-f", + menu: { + title: "Hello", + icon: undefined, + defaultCollapsed: false, + menuItems: [ + { + text: "Menu item", + to: "/hello", + children: [], + sort: 1, + }, + { + text: "Opción del menú", + to: "/hola/1", + children: [], + sort: 2, + }, + { + if: true, + text: "Fixed item", + activeIncludes: ["/any"], + sort: 3, + to: "/hola/2", + children: [], + }, + ], + }, + subMenu: null, + }); + expect(fakeKernel.fulfilStoryboardI18n).toBeCalledWith(["hola"]); + }); + it("should construct menu with injected group", async () => { const menuBar = { menuId: "menu-g", diff --git a/packages/brick-kit/src/internal/menu.ts b/packages/brick-kit/src/internal/menu.ts index 0f45554b2a..f110338c7b 100644 --- a/packages/brick-kit/src/internal/menu.ts +++ b/packages/brick-kit/src/internal/menu.ts @@ -5,6 +5,7 @@ import { SidebarMenu, MenuRawData, MenuItemRawData, + MicroApp, } from "@next-core/brick-types"; import { isEvaluable, isObject, preevaluate } from "@next-core/brick-utils"; import { @@ -24,14 +25,17 @@ import i18next from "i18next"; const symbolAppId = Symbol("appId"); const symbolMenuI18nNamespace = Symbol("menuI18nNamespace"); +const symbolOverrideApp = Symbol("overriceApp"); interface RuntimeMenuItemRawData extends MenuItemRawData { [symbolAppId]?: string; [symbolMenuI18nNamespace]?: string; + [symbolOverrideApp]?: MicroApp; } interface RuntimeMenuRawData extends MenuRawData { [symbolMenuI18nNamespace]?: string; + [symbolOverrideApp]?: MicroApp; } // Caching menu requests to avoid flicker. @@ -219,6 +223,7 @@ function processGroupInject( ), [symbolAppId]: menu.app[0].appId, [symbolMenuI18nNamespace]: menuWithI18n.get(menu), + [symbolOverrideApp]: menu.overrideApp, }; }); } @@ -237,14 +242,22 @@ async function loadDynamicMenuItems( overrideAppId !== context.app.id && attemptToVisit(menu.itemsResolve, ["APP", "I18N"]) ) { - const storyboard = kernel.bootstrapData.storyboards.find( - (story) => story.app.id === overrideAppId - ); - newContext = { - ...context, - overrideApp: storyboard?.app, - appendI18nNamespace: menuWithI18n.get(menu), - }; + if (window.STANDALONE_MICRO_APPS) { + newContext = { + ...context, + overrideApp: menu.overrideApp, + appendI18nNamespace: menuWithI18n.get(menu), + }; + } else { + const storyboard = kernel.bootstrapData.storyboards.find( + (story) => story.app.id === overrideAppId + ); + newContext = { + ...context, + overrideApp: storyboard?.app, + appendI18nNamespace: menuWithI18n.get(menu), + }; + } } await _internalApiGetResolver().resolveOne( "reference", @@ -459,14 +472,22 @@ function computeRealValueWithOverrideApp< overrideAppId !== context.app.id && attemptToVisit(data, ["APP", "I18N"]) ) { - const storyboard = kernel.bootstrapData.storyboards.find( - (story) => story.app.id === overrideAppId - ); - newContext = { - ...context, - overrideApp: storyboard?.app, - appendI18nNamespace: data[symbolMenuI18nNamespace], - }; + if (window.STANDALONE_MICRO_APPS) { + newContext = { + ...context, + overrideApp: data[symbolOverrideApp], + appendI18nNamespace: data[symbolMenuI18nNamespace], + }; + } else { + const storyboard = kernel.bootstrapData.storyboards.find( + (story) => story.app.id === overrideAppId + ); + newContext = { + ...context, + overrideApp: storyboard?.app, + appendI18nNamespace: data[symbolMenuI18nNamespace], + }; + } } return computeRealValue(data, newContext, true, { ignoreSymbols: true, diff --git a/packages/brick-types/src/menu.ts b/packages/brick-types/src/menu.ts index 6039ec1271..fe2221821a 100644 --- a/packages/brick-types/src/menu.ts +++ b/packages/brick-types/src/menu.ts @@ -1,7 +1,7 @@ import { LocationDescriptor } from "history"; import { ThemeType } from "@ant-design/compatible/lib/icon"; import { IconName, IconPrefix } from "@fortawesome/fontawesome-svg-core"; -import { MetaI18n, ResolveConf } from "./manifest"; +import { MetaI18n, ResolveConf, MicroApp } from "./manifest"; /** * 侧边栏菜单配置。 @@ -165,6 +165,7 @@ export interface MenuRawData { dynamicItems?: boolean; itemsResolve?: ResolveConf; i18n?: MetaI18n; + overrideApp?: MicroApp; } /** 原始菜单项数据。 */