diff --git a/workspaces/homepage/.changeset/narrow-homepage-public-api.md b/workspaces/homepage/.changeset/narrow-homepage-public-api.md new file mode 100644 index 00000000000..a4d38ac8461 --- /dev/null +++ b/workspaces/homepage/.changeset/narrow-homepage-public-api.md @@ -0,0 +1,5 @@ +--- +'@red-hat-developer-hub/backstage-plugin-homepage': minor +--- + +Narrow the main package entry point to the default plugin export and translations module. Move plugin implementation to `plugin.ts` and remove deprecated public API aliases. Serve the demo homepage at `/homepage` and redirect `/` there. diff --git a/workspaces/homepage/app-config.yaml b/workspaces/homepage/app-config.yaml index e12cc8bd732..8f6f3a1422e 100644 --- a/workspaces/homepage/app-config.yaml +++ b/workspaces/homepage/app-config.yaml @@ -1,25 +1,31 @@ app: title: Homepage Backstage App baseUrl: http://localhost:3000 + packages: all + extensions: - api:app/app-language: config: availableLanguages: ['en', 'de', 'fr', 'it', 'es', 'ja'] defaultLanguage: 'en' - # Disable the nav items that we're manually rendering in packages/app/src/modules/nav/Sidebar.tsx + - api:home/visits: true + - app-root-element:home/visit-listener: true + # Community home page (optional). Disable when using page:homepage alone. - page:home: config: - path: /home + path: /home # Default, just to make it more explicit title: Home + # Homepage-owned page (configurable path). Disable with page:homepage: false. - page:homepage: config: - path: / - title: Dynamic Homepage + path: /homepage # Default is / but to make it more explicit here + title: Homepage + - home-page-layout:homepage/dynamic-homepage-layout: config: customizable: true # false for read-only homepage layout diff --git a/workspaces/homepage/packages/app/src/App.tsx b/workspaces/homepage/packages/app/src/App.tsx index b157ac61506..f04998c1ff6 100644 --- a/workspaces/homepage/packages/app/src/App.tsx +++ b/workspaces/homepage/packages/app/src/App.tsx @@ -15,22 +15,28 @@ */ import { createApp } from '@backstage/frontend-defaults'; +import { + createFrontendModule, + PageBlueprint, +} from '@backstage/frontend-plugin-api'; +import { Navigate } from 'react-router-dom'; import { navModule } from './modules/nav'; import { signInModule } from './modules/signIn'; -import { - homepagePlugin, - homepageHomeModule, - homepageTranslationsModule, -} from '@red-hat-developer-hub/backstage-plugin-homepage'; -import rhdhThemeModule from '@red-hat-developer-hub/backstage-plugin-theme'; -export default createApp({ - features: [ - rhdhThemeModule, - navModule, - signInModule, - homepagePlugin, - homepageHomeModule, - homepageTranslationsModule, +const homeRedirectModule = createFrontendModule({ + pluginId: 'app', + extensions: [ + PageBlueprint.make({ + name: 'home-redirect', + params: { + path: '/', + noHeader: true, + loader: async () => , + }, + }), ], }); + +export default createApp({ + features: [navModule, signInModule, homeRedirectModule], +}); diff --git a/workspaces/homepage/plugins/homepage/dev/index.tsx b/workspaces/homepage/plugins/homepage/dev/index.tsx index 4358d64ec54..5f13f225942 100644 --- a/workspaces/homepage/plugins/homepage/dev/index.tsx +++ b/workspaces/homepage/plugins/homepage/dev/index.tsx @@ -46,11 +46,12 @@ import { starredEntitiesApiRef, } from '@backstage/plugin-catalog-react'; import homePlugin from '@backstage/plugin-home/alpha'; -import { - homepagePlugin, - homepageHomeModule, - homepageTranslationsModule, -} from '@red-hat-developer-hub/backstage-plugin-homepage'; +import homepagePlugin from '@red-hat-developer-hub/backstage-plugin-homepage/'; +// import { +// homepageHomeModule, +// } from '@red-hat-developer-hub/backstage-plugin-homepage'; +import homepageTranslationsModule from '@red-hat-developer-hub/backstage-plugin-homepage/homepage-translations-module'; + import rhdhThemeModule from '@red-hat-developer-hub/backstage-plugin-theme'; import { quickAccessApiRef } from '../src/api'; import { visitsApiRef } from '@backstage/plugin-home'; @@ -157,7 +158,7 @@ const app = createApp({ searchPlugin, homePlugin, homepagePlugin, - homepageHomeModule, + // homepageHomeModule, homepageTranslationsModule, homepageApiMocksModule, catalogDevModule, diff --git a/workspaces/homepage/plugins/homepage/report.api.md b/workspaces/homepage/plugins/homepage/report.api.md index 795f4eb0b87..d5057507c0f 100644 --- a/workspaces/homepage/plugins/homepage/report.api.md +++ b/workspaces/homepage/plugins/homepage/report.api.md @@ -23,11 +23,6 @@ import { RouteRef } from '@backstage/frontend-plugin-api'; import { TranslationRef } from '@backstage/frontend-plugin-api'; import { TranslationResource } from '@backstage/frontend-plugin-api'; -// @public -const homepageHomeModule: FrontendModule; -export { homepageHomeModule as homePageModule }; -export { homepageHomeModule }; - // @public const homepagePlugin: OverridableFrontendPlugin< { @@ -304,11 +299,6 @@ const homepagePlugin: OverridableFrontendPlugin< } >; export default homepagePlugin; -export { homepagePlugin as homePagePlugin }; -export { homepagePlugin }; - -// @public -export const homepageRouteRef: RouteRef; // @public export const homepageTranslationRef: TranslationRef< diff --git a/workspaces/homepage/plugins/homepage/src/index.ts b/workspaces/homepage/plugins/homepage/src/index.ts index 3b057af934f..e6d22d49195 100644 --- a/workspaces/homepage/plugins/homepage/src/index.ts +++ b/workspaces/homepage/plugins/homepage/src/index.ts @@ -28,121 +28,8 @@ ClassNameGenerator.configure(componentName => { : `v5-${componentName}`; }); -import { TranslationBlueprint } from '@backstage/plugin-app-react'; -import { - createFrontendModule, - createFrontendPlugin, -} from '@backstage/frontend-plugin-api'; -import { - catalogStarredWidget, - communityHomeWidgets, - disableRandomJoke, - disableToolkit, - entitySectionWidget, - featuredDocsCardWidget, - onboardingSectionWidget, - overrideHomeCatalogStarredWidget, - quickAccessCardWidget, - RecentlyVisitedWidget, - searchBarWidget, - templateSectionWidget, - TopVisitedWidget, -} from './extensions/homePageCards'; -import { homepageTranslations } from './translations'; -import { homePageLayoutExtension } from './extensions/homePageLayoutExtension'; -import { homepagePage } from './extensions/homepagePage'; -import { defaultWidgetsApi, quickAccessApi } from './extensions/apis'; -import { homepageRouteRef } from './homepageRouteRef'; +export { homepagePlugin as default } from './plugin'; -export { homepageRouteRef } from './homepageRouteRef'; - -/** - * Extensions owned by the homepage plugin. - * - * Widgets/layout attach to `page:homepage`. Persona filtering via - * homepage-backend is applied only by that layout. - */ -const homepageExtensions = [ - homepagePage, - homePageLayoutExtension, - onboardingSectionWidget, - entitySectionWidget, - templateSectionWidget, - defaultWidgetsApi, - quickAccessApi, - quickAccessCardWidget, - featuredDocsCardWidget, - searchBarWidget, - TopVisitedWidget, - RecentlyVisitedWidget, - catalogStarredWidget, -]; - -/** - * Homepage frontend plugin (`pluginId: homepage`). - * - * @public - */ -export const homepagePlugin = createFrontendPlugin({ - pluginId: 'homepage', - extensions: homepageExtensions, - routes: { - root: homepageRouteRef, - }, -}); - -/** - * Optional module for when community `@backstage/plugin-home` is also installed. - * - * Mirrors RH widgets onto `page:home` (no RH layout / no homepage-backend - * filtering) and disables community toolkit / joke demos and overrides the starred widget. - * - * @public - */ -export const homepageHomeModule = createFrontendModule({ - pluginId: 'home', - extensions: [ - ...communityHomeWidgets, - overrideHomeCatalogStarredWidget, - disableToolkit, - disableRandomJoke, - ], -}); - -/** - * @public - * @deprecated Use {@link homepageHomeModule}. - */ -export { homepageHomeModule as homePageModule }; - -/** - * @public - * @deprecated Use {@link homepagePlugin}. - */ -export { homepagePlugin as homePagePlugin }; - -/** - * Translation module for the Dynamic Home Page plugin. - * - * @public - */ -export const homepageTranslationsModule = createFrontendModule({ - pluginId: 'app', - extensions: [ - TranslationBlueprint.make({ - name: 'homepage-translations', - params: { - resource: homepageTranslations, - }, - }), - ], -}); +export { homepageTranslationsModule } from './plugin'; export { homepageTranslationRef, homepageTranslations } from './translations'; - -/** - * Default export required for Module Federation to emit the NFS expose. - * - * @public - */ -export default homepagePlugin; diff --git a/workspaces/homepage/plugins/homepage/src/nfsExports.test.ts b/workspaces/homepage/plugins/homepage/src/plugin.test.ts similarity index 97% rename from workspaces/homepage/plugins/homepage/src/nfsExports.test.ts rename to workspaces/homepage/plugins/homepage/src/plugin.test.ts index c9646b88ee3..92af21f555c 100644 --- a/workspaces/homepage/plugins/homepage/src/nfsExports.test.ts +++ b/workspaces/homepage/plugins/homepage/src/plugin.test.ts @@ -20,9 +20,7 @@ import { homepageHomeModule, homepagePlugin, homepageTranslationsModule, - homePageModule, - homePagePlugin, -} from '.'; +} from './plugin'; import { homepageTranslationRef, homepageTranslations } from './translations'; import { homePageLayoutExtension } from './extensions/homePageLayoutExtension'; import { HOMEPAGE_PAGE_ID } from './extensions/homepageAttach'; @@ -40,6 +38,7 @@ import { RecentlyVisitedWidget, TopVisitedWidget, } from './extensions/homePageCards'; + import { quickAccessApi, defaultWidgetsApi } from './extensions/apis'; type ExtensionAttach = { id: string; input: string }; @@ -75,7 +74,6 @@ describe('Dynamic Home Page plugin (NFS)', () => { expect(homepagePlugin.$$type).toBe('@backstage/FrontendPlugin'); expect(homepagePlugin.id).toBe('homepage'); expect(homepagePlugin.id).not.toBe(homePlugin.id); - expect(homePagePlugin).toBe(homepagePlugin); expect(homepagePlugin.getExtension(HOMEPAGE_PAGE_ID)).toBeDefined(); expect( homepagePlugin.getExtension( @@ -98,7 +96,6 @@ describe('Dynamic Home Page plugin (NFS)', () => { expect(homepageHomeModule).toBeDefined(); expect(homepageHomeModule.$$type).toBe('@backstage/FrontendModule'); expect(homepageHomeModule.pluginId).toBe('home'); - expect(homePageModule).toBe(homepageHomeModule); expect(communityHomeWidgets).toHaveLength(9); const extensions = getRuntimeExtensions(homepageHomeModule); diff --git a/workspaces/homepage/plugins/homepage/src/plugin.ts b/workspaces/homepage/plugins/homepage/src/plugin.ts new file mode 100644 index 00000000000..56de4596d5b --- /dev/null +++ b/workspaces/homepage/plugins/homepage/src/plugin.ts @@ -0,0 +1,115 @@ +/* + * Copyright Red Hat, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { TranslationBlueprint } from '@backstage/plugin-app-react'; +import { + createFrontendModule, + createFrontendPlugin, +} from '@backstage/frontend-plugin-api'; +import { + catalogStarredWidget, + communityHomeWidgets, + disableRandomJoke, + disableToolkit, + entitySectionWidget, + featuredDocsCardWidget, + onboardingSectionWidget, + overrideHomeCatalogStarredWidget, + quickAccessCardWidget, + RecentlyVisitedWidget, + searchBarWidget, + templateSectionWidget, + TopVisitedWidget, +} from './extensions/homePageCards'; +import { homepageTranslations } from './translations'; +import { homePageLayoutExtension } from './extensions/homePageLayoutExtension'; +import { homepagePage } from './extensions/homepagePage'; +import { defaultWidgetsApi, quickAccessApi } from './extensions/apis'; +import { homepageRouteRef } from './homepageRouteRef'; + +export { homepageRouteRef } from './homepageRouteRef'; + +/** + * Extensions owned by the homepage plugin. + * + * Widgets/layout attach to `page:homepage`. Persona filtering via + * homepage-backend is applied only by that layout. + */ +const homepageExtensions = [ + homepagePage, + homePageLayoutExtension, + onboardingSectionWidget, + entitySectionWidget, + templateSectionWidget, + defaultWidgetsApi, + quickAccessApi, + quickAccessCardWidget, + featuredDocsCardWidget, + searchBarWidget, + TopVisitedWidget, + RecentlyVisitedWidget, + catalogStarredWidget, +]; + +/** + * Homepage frontend plugin (`pluginId: homepage`). + * + * @public + */ +export const homepagePlugin = createFrontendPlugin({ + pluginId: 'homepage', + extensions: homepageExtensions, + routes: { + root: homepageRouteRef, + }, +}); + +/** + * Optional module for when community `@backstage/plugin-home` is also installed. + * + * Mirrors RH widgets onto `page:home` (no RH layout / no homepage-backend + * filtering) and disables community toolkit / joke demos and overrides the starred widget. + * + * @public + */ +export const homepageHomeModule = createFrontendModule({ + pluginId: 'home', + extensions: [ + ...communityHomeWidgets, + overrideHomeCatalogStarredWidget, + disableToolkit, + disableRandomJoke, + ], +}); + +/** + * Translation module for the Dynamic Home Page plugin. + * + * @public + */ +export const homepageTranslationsModule = createFrontendModule({ + pluginId: 'app', + extensions: [ + TranslationBlueprint.make({ + name: 'homepage-translations', + params: { + resource: homepageTranslations, + }, + }), + ], +}); + +export { homepageTranslationRef, homepageTranslations } from './translations';