From 7155c30a889b5f8ff45b6d401ee491b98e9ec33f Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Fri, 19 Jan 2024 11:17:56 +0100 Subject: [PATCH 1/5] core-compat-api: added convertLegacyRouteRefs Signed-off-by: Patrik Oldsberg --- .changeset/olive-singers-accept.md | 5 +++ packages/core-compat-api/api-report.md | 21 +++++++++++ .../src/convertLegacyRouteRef.ts | 37 +++++++++++++++++++ packages/core-compat-api/src/index.ts | 6 ++- 4 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 .changeset/olive-singers-accept.md diff --git a/.changeset/olive-singers-accept.md b/.changeset/olive-singers-accept.md new file mode 100644 index 0000000000..7e8cf7ae8d --- /dev/null +++ b/.changeset/olive-singers-accept.md @@ -0,0 +1,5 @@ +--- +'@backstage/core-compat-api': patch +--- + +Added `convertLegacyRouteRefs` for bulk conversion of plugin routes. diff --git a/packages/core-compat-api/api-report.md b/packages/core-compat-api/api-report.md index 494747be60..a7aae2b5b9 100644 --- a/packages/core-compat-api/api-report.md +++ b/packages/core-compat-api/api-report.md @@ -40,5 +40,26 @@ export function convertLegacyRouteRef< ref: ExternalRouteRef, ): ExternalRouteRef_2; +// @public +export function convertLegacyRouteRefs< + TRefs extends { + [name in string]: RouteRef | SubRouteRef | ExternalRouteRef; + }, +>( + refs: TRefs, +): { + [KName in keyof TRefs]: ToNewRouteRef; +}; + +// @public +export type ToNewRouteRef = + T extends RouteRef + ? RouteRef_2 + : T extends SubRouteRef + ? SubRouteRef_2 + : T extends ExternalRouteRef + ? ExternalRouteRef_2 + : never; + // (No @packageDocumentation comment for this package) ``` diff --git a/packages/core-compat-api/src/convertLegacyRouteRef.ts b/packages/core-compat-api/src/convertLegacyRouteRef.ts index c5ee603722..36311dc081 100644 --- a/packages/core-compat-api/src/convertLegacyRouteRef.ts +++ b/packages/core-compat-api/src/convertLegacyRouteRef.ts @@ -40,6 +40,43 @@ import { toInternalSubRouteRef } from '../../frontend-plugin-api/src/routing/Sub // eslint-disable-next-line @backstage/no-relative-monorepo-imports import { toInternalExternalRouteRef } from '../../frontend-plugin-api/src/routing/ExternalRouteRef'; +/** + * Converts a legacy route ref type to the new system. + * + * @public + */ +export type ToNewRouteRef< + T extends LegacyRouteRef | LegacySubRouteRef | LegacyExternalRouteRef, +> = T extends LegacyRouteRef + ? RouteRef + : T extends LegacySubRouteRef + ? SubRouteRef + : T extends LegacyExternalRouteRef + ? ExternalRouteRef + : never; + +/** + * Converts a collection of legacy route refs to the new system. + * This is particularly useful when defining plugin `routes` and `externalRoutes`. + * + * @public + */ +export function convertLegacyRouteRefs< + TRefs extends { + [name in string]: + | LegacyRouteRef + | LegacySubRouteRef + | LegacyExternalRouteRef; + }, +>(refs: TRefs): { [KName in keyof TRefs]: ToNewRouteRef } { + return Object.fromEntries( + Object.entries(refs).map(([name, ref]) => [ + name, + convertLegacyRouteRef(ref as LegacyRouteRef), + ]), + ) as { [KName in keyof TRefs]: ToNewRouteRef }; +} + /** * A temporary helper to convert a legacy route ref to the new system. * diff --git a/packages/core-compat-api/src/index.ts b/packages/core-compat-api/src/index.ts index 68e5d9cf19..b632bf8a57 100644 --- a/packages/core-compat-api/src/index.ts +++ b/packages/core-compat-api/src/index.ts @@ -16,4 +16,8 @@ export * from './compatWrapper'; export { convertLegacyApp } from './convertLegacyApp'; -export { convertLegacyRouteRef } from './convertLegacyRouteRef'; +export { + convertLegacyRouteRef, + convertLegacyRouteRefs, + type ToNewRouteRef, +} from './convertLegacyRouteRef'; From 2f2a1d2ad24a5c9ff5a613e9e7abdad6b0102c4d Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Fri, 19 Jan 2024 11:19:43 +0100 Subject: [PATCH 2/5] core-compat-api: forward routes to converted plugins Signed-off-by: Patrik Oldsberg --- .changeset/twenty-taxis-mate.md | 5 +++++ packages/core-compat-api/src/collectLegacyRoutes.tsx | 7 ++++++- 2 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 .changeset/twenty-taxis-mate.md diff --git a/.changeset/twenty-taxis-mate.md b/.changeset/twenty-taxis-mate.md new file mode 100644 index 0000000000..ab3cc6d406 --- /dev/null +++ b/.changeset/twenty-taxis-mate.md @@ -0,0 +1,5 @@ +--- +'@backstage/core-compat-api': patch +--- + +Plugins converted by `convertLegacyApp` now have their `routes` and `externalRoutes` included as well, allowing the to be used to bind external routes in configuration. diff --git a/packages/core-compat-api/src/collectLegacyRoutes.tsx b/packages/core-compat-api/src/collectLegacyRoutes.tsx index 4d560b81d5..7ddb8c4f7e 100644 --- a/packages/core-compat-api/src/collectLegacyRoutes.tsx +++ b/packages/core-compat-api/src/collectLegacyRoutes.tsx @@ -32,7 +32,10 @@ import { } from '@backstage/frontend-plugin-api'; import React, { Children, ReactNode, isValidElement } from 'react'; import { Route, Routes } from 'react-router-dom'; -import { convertLegacyRouteRef } from './convertLegacyRouteRef'; +import { + convertLegacyRouteRef, + convertLegacyRouteRefs, +} from './convertLegacyRouteRef'; import { compatWrapper } from './compatWrapper'; /* @@ -244,6 +247,8 @@ export function collectLegacyRoutes( createApiExtension({ factory }), ), ], + routes: convertLegacyRouteRefs(plugin.routes ?? {}), + externalRoutes: convertLegacyRouteRefs(plugin.externalRoutes ?? {}), }), ); } From 912ca7b583e01884638bff04859cd4d2871e0eac Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Fri, 19 Jan 2024 11:20:39 +0100 Subject: [PATCH 3/5] plugins: use convertLegacyRouteRefs Signed-off-by: Patrik Oldsberg --- .changeset/hot-pillows-poke.md | 11 +++++++++++ plugins/catalog/src/alpha/plugin.tsx | 22 +++++++++++----------- plugins/graphiql/src/alpha.tsx | 7 ++++--- plugins/scaffolder/src/alpha.tsx | 25 +++++++++++++------------ plugins/search/src/alpha.tsx | 7 ++++--- plugins/tech-radar/src/alpha.tsx | 7 ++++--- plugins/techdocs/src/alpha.tsx | 11 ++++++----- plugins/user-settings/src/alpha.tsx | 7 ++++--- 8 files changed, 57 insertions(+), 40 deletions(-) create mode 100644 .changeset/hot-pillows-poke.md diff --git a/.changeset/hot-pillows-poke.md b/.changeset/hot-pillows-poke.md new file mode 100644 index 0000000000..8060e7121f --- /dev/null +++ b/.changeset/hot-pillows-poke.md @@ -0,0 +1,11 @@ +--- +'@backstage/plugin-user-settings': patch +'@backstage/plugin-scaffolder': patch +'@backstage/plugin-tech-radar': patch +'@backstage/plugin-graphiql': patch +'@backstage/plugin-techdocs': patch +'@backstage/plugin-catalog': patch +'@backstage/plugin-search': patch +--- + +Use `convertLegacyRouteRefs` to define routes in `/alpha` export plugin. diff --git a/plugins/catalog/src/alpha/plugin.tsx b/plugins/catalog/src/alpha/plugin.tsx index 99aacd27da..9a964c4e46 100644 --- a/plugins/catalog/src/alpha/plugin.tsx +++ b/plugins/catalog/src/alpha/plugin.tsx @@ -14,7 +14,7 @@ * limitations under the License. */ -import { convertLegacyRouteRef } from '@backstage/core-compat-api'; +import { convertLegacyRouteRefs } from '@backstage/core-compat-api'; import { createPlugin } from '@backstage/frontend-plugin-api'; import { entityRouteRef } from '@backstage/plugin-catalog-react'; @@ -38,16 +38,16 @@ import searchResultItems from './searchResultItems'; /** @alpha */ export default createPlugin({ id: 'catalog', - routes: { - catalogIndex: convertLegacyRouteRef(rootRouteRef), - catalogEntity: convertLegacyRouteRef(entityRouteRef), - }, - externalRoutes: { - viewTechDoc: convertLegacyRouteRef(viewTechDocRouteRef), - createComponent: convertLegacyRouteRef(createComponentRouteRef), - createFromTemplate: convertLegacyRouteRef(createFromTemplateRouteRef), - unregisterRedirect: convertLegacyRouteRef(unregisterRedirectRouteRef), - }, + routes: convertLegacyRouteRefs({ + catalogIndex: rootRouteRef, + catalogEntity: entityRouteRef, + }), + externalRoutes: convertLegacyRouteRefs({ + viewTechDoc: viewTechDocRouteRef, + createComponent: createComponentRouteRef, + createFromTemplate: createFromTemplateRouteRef, + unregisterRedirect: unregisterRedirectRouteRef, + }), extensions: [ ...apis, ...pages, diff --git a/plugins/graphiql/src/alpha.tsx b/plugins/graphiql/src/alpha.tsx index fdd343020d..086f397d7a 100644 --- a/plugins/graphiql/src/alpha.tsx +++ b/plugins/graphiql/src/alpha.tsx @@ -37,6 +37,7 @@ import { graphiQLRouteRef } from './route-refs'; import { compatWrapper, convertLegacyRouteRef, + convertLegacyRouteRefs, } from '@backstage/core-compat-api'; /** @alpha */ @@ -128,7 +129,7 @@ export default createPlugin({ graphiqlGitlabGraphiQLEndpointExtension, graphiqlNavItem, ], - routes: { - root: convertLegacyRouteRef(graphiQLRouteRef), - }, + routes: convertLegacyRouteRefs({ + root: graphiQLRouteRef, + }), }); diff --git a/plugins/scaffolder/src/alpha.tsx b/plugins/scaffolder/src/alpha.tsx index 0d079f9c40..37e2978802 100644 --- a/plugins/scaffolder/src/alpha.tsx +++ b/plugins/scaffolder/src/alpha.tsx @@ -29,6 +29,7 @@ import CreateComponentIcon from '@material-ui/icons/AddCircleOutline'; import { compatWrapper, convertLegacyRouteRef, + convertLegacyRouteRefs, } from '@backstage/core-compat-api'; import { scmIntegrationsApiRef } from '@backstage/integration-react'; import { scaffolderApiRef } from '@backstage/plugin-scaffolder-react'; @@ -85,17 +86,17 @@ const scaffolderNavItem = createNavItemExtension({ /** @alpha */ export default createPlugin({ id: 'scaffolder', - routes: { - root: convertLegacyRouteRef(rootRouteRef), - selectedTemplate: convertLegacyRouteRef(selectedTemplateRouteRef), - ongoingTask: convertLegacyRouteRef(scaffolderTaskRouteRef), - actions: convertLegacyRouteRef(actionsRouteRef), - listTasks: convertLegacyRouteRef(scaffolderListTaskRouteRef), - edit: convertLegacyRouteRef(editRouteRef), - }, - externalRoutes: { - registerComponent: convertLegacyRouteRef(registerComponentRouteRef), - viewTechDoc: convertLegacyRouteRef(viewTechDocRouteRef), - }, + routes: convertLegacyRouteRefs({ + root: rootRouteRef, + selectedTemplate: selectedTemplateRouteRef, + ongoingTask: scaffolderTaskRouteRef, + actions: actionsRouteRef, + listTasks: scaffolderListTaskRouteRef, + edit: editRouteRef, + }), + externalRoutes: convertLegacyRouteRefs({ + registerComponent: registerComponentRouteRef, + viewTechDoc: viewTechDocRouteRef, + }), extensions: [scaffolderApi, scaffolderPage, scaffolderNavItem], }); diff --git a/plugins/search/src/alpha.tsx b/plugins/search/src/alpha.tsx index a3a5023693..4f654548f5 100644 --- a/plugins/search/src/alpha.tsx +++ b/plugins/search/src/alpha.tsx @@ -70,6 +70,7 @@ import { UrlUpdater } from './components/SearchPage/SearchPage'; import { compatWrapper, convertLegacyRouteRef, + convertLegacyRouteRefs, } from '@backstage/core-compat-api'; /** @alpha */ @@ -248,7 +249,7 @@ export const searchNavItem = createNavItemExtension({ export default createPlugin({ id: 'search', extensions: [searchApi, searchPage, searchNavItem], - routes: { - root: convertLegacyRouteRef(rootRouteRef), - }, + routes: convertLegacyRouteRefs({ + root: rootRouteRef, + }), }); diff --git a/plugins/tech-radar/src/alpha.tsx b/plugins/tech-radar/src/alpha.tsx index 1fb5fa06f3..54e209fae3 100644 --- a/plugins/tech-radar/src/alpha.tsx +++ b/plugins/tech-radar/src/alpha.tsx @@ -27,6 +27,7 @@ import { SampleTechRadarApi } from './sample'; import { compatWrapper, convertLegacyRouteRef, + convertLegacyRouteRefs, } from '@backstage/core-compat-api'; import { rootRouteRef } from './plugin'; @@ -61,7 +62,7 @@ export const techRadarApi = createApiExtension({ export default createPlugin({ id: 'tech-radar', extensions: [techRadarPage, techRadarApi], - routes: { - root: convertLegacyRouteRef(rootRouteRef), - }, + routes: convertLegacyRouteRefs({ + root: rootRouteRef, + }), }); diff --git a/plugins/techdocs/src/alpha.tsx b/plugins/techdocs/src/alpha.tsx index ef564d469a..88dce3b48e 100644 --- a/plugins/techdocs/src/alpha.tsx +++ b/plugins/techdocs/src/alpha.tsx @@ -34,6 +34,7 @@ import { import { compatWrapper, convertLegacyRouteRef, + convertLegacyRouteRefs, } from '@backstage/core-compat-api'; import { techdocsApiRef, @@ -168,9 +169,9 @@ export default createPlugin({ techDocsEntityContent, techDocsSearchResultListItemExtension, ], - routes: { - root: convertLegacyRouteRef(rootRouteRef), - docRoot: convertLegacyRouteRef(rootDocsRouteRef), - entityContent: convertLegacyRouteRef(rootCatalogDocsRouteRef), - }, + routes: convertLegacyRouteRefs({ + root: rootRouteRef, + docRoot: rootDocsRouteRef, + entityContent: rootCatalogDocsRouteRef, + }), }); diff --git a/plugins/user-settings/src/alpha.tsx b/plugins/user-settings/src/alpha.tsx index 5dabd70739..f14db7233d 100644 --- a/plugins/user-settings/src/alpha.tsx +++ b/plugins/user-settings/src/alpha.tsx @@ -22,6 +22,7 @@ import { } from '@backstage/frontend-plugin-api'; import { convertLegacyRouteRef, + convertLegacyRouteRefs, compatWrapper, } from '@backstage/core-compat-api'; import SettingsIcon from '@material-ui/icons/Settings'; @@ -65,7 +66,7 @@ export const settingsNavItem = createNavItemExtension({ export default createPlugin({ id: 'user-settings', extensions: [userSettingsPage, settingsNavItem], - routes: { - root: convertLegacyRouteRef(settingsRouteRef), - }, + routes: convertLegacyRouteRefs({ + root: settingsRouteRef, + }), }); From 53d2a7dcc2e224b6fa155c20f7146e232e3a9b1f Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Fri, 19 Jan 2024 11:33:35 +0100 Subject: [PATCH 4/5] app-next: add route binding from migrated app to a converted one Signed-off-by: Patrik Oldsberg --- packages/app-next/app-config.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/app-next/app-config.yaml b/packages/app-next/app-config.yaml index 77f4284455..1b77205d5e 100644 --- a/packages/app-next/app-config.yaml +++ b/packages/app-next/app-config.yaml @@ -5,6 +5,7 @@ app: bindings: plugin.pages.externalRoutes.pageX: plugin.pages.routes.pageX plugin.catalog.externalRoutes.viewTechDoc: plugin.techdocs.routes.docRoot + plugin.catalog.externalRoutes.createComponent: plugin.catalog-import.routes.importPage extensions: # - apis.plugin.graphiql.browse.gitlab: true From d5d9912f3b7a444441bac4f57c2056468cd81713 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Fri, 19 Jan 2024 12:06:56 +0100 Subject: [PATCH 5/5] Apply suggestions from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw Signed-off-by: Patrik Oldsberg --- .changeset/twenty-taxis-mate.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/twenty-taxis-mate.md b/.changeset/twenty-taxis-mate.md index ab3cc6d406..65ed158e9b 100644 --- a/.changeset/twenty-taxis-mate.md +++ b/.changeset/twenty-taxis-mate.md @@ -2,4 +2,4 @@ '@backstage/core-compat-api': patch --- -Plugins converted by `convertLegacyApp` now have their `routes` and `externalRoutes` included as well, allowing the to be used to bind external routes in configuration. +Plugins converted by `convertLegacyApp` now have their `routes` and `externalRoutes` included as well, allowing them to be used to bind external routes in configuration.